diff --git a/.github/workflows/Example.yml b/.github/workflows/Example.yml index 57eaf579..aa85cfec 100644 --- a/.github/workflows/Example.yml +++ b/.github/workflows/Example.yml @@ -13,23 +13,23 @@ on: - 'Project.toml' jobs: - sync-files: + jupyter: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [windows-latest] # ubuntu-latest file-name: [manipulation, modelica_conference_2021, multiple_instances, multiprocessing, multithreading, parameterize, simulate, parameter_optimization] - julia-version: ['1.8'] + julia-version: ['1.10'] julia-arch: [x64] experimental: [false] steps: - name: "Check out repository" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Set up Julia" - uses: julia-actions/setup-julia@v1 + uses: julia-actions/setup-julia@latest with: version: ${{ matrix.julia-version }} arch: ${{ matrix.julia-arch }} @@ -44,59 +44,92 @@ jobs: env: FILE: examples/src/${{ matrix.file-name }}.ipynb run: | - jupyter nbconvert --ExecutePreprocessor.kernel_name="julia-1.8" --to notebook --inplace --execute ${{ env.FILE }} + jupyter nbconvert --ExecutePreprocessor.kernel_name="julia-${{ matrix.julia-version }}" --to notebook --inplace --execute ${{ env.FILE }} jupyter nbconvert --to script ${{ env.FILE }} jupyter nbconvert --to markdown ${{ env.FILE }} - - name: Archive examples artifacts - if: success() && matrix.os == 'windows-latest' - uses: actions/upload-artifact@v3 - with: - name: examples - path: examples/src/${{ matrix.file-name }}* + - name: "run generated jl script to determine success of example building" + run: julia --project=examples/ examples/${{ matrix.file-name }}.jl - auto-commit: - needs: sync-files - if: github.event_name != 'pull_request' + - name: "auto-commit (retry on merge)" + if: success() && github.event_name != 'pull_request' && github.branch == 'main' + uses: nick-fields/retry@v3 + env: + CI_COMMIT_MESSAGE: example-${{ matrix.os }}-${{ matrix.file-name }}-${{ matrix.julia-version }}-${{ matrix.julia-arch }}-${{ matrix.experimental }}[${{ github.ref }}] + CI_COMMIT_AUTHOR: github-actions[bot] + EXAMPLES_PATH: examples + # Fetch all and clear the stash list. Include all files from the examples folder to the stash and switch the branch. + # Reset the branch and remove all current files in the examples folder. + # Checkout the last stash to restore the new notebooks and apply the stash index to restore all other new files in the folder. + with: + timeout_minutes: 999 + max_attempts: 10 + warning_on_retry: false + shell: bash + command: | + git fetch --all + git stash clear + git stash --include-untracked -- ${{ env.EXAMPLES_PATH }} + git switch examples + git reset --hard origin/examples + git checkout stash -f -- ${{ env.EXAMPLES_PATH }} + git stash apply --index + git stash drop + git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}" + git config --global user.email "${{ env.CI_COMMIT_AUTHOR }}@users.noreply.github.com" + git config --global core.autocrlf false + git add ${{ env.EXAMPLES_PATH }} + git commit -m "${{ env.CI_COMMIT_MESSAGE }}" + git push origin examples || (git reset --soft HEAD~1 && (exit 1)) + pluto: runs-on: ubuntu-latest steps: - - name: Check out repository + - name: "Check out repository" uses: actions/checkout@v3 - - name: Download examples - uses: actions/download-artifact@v3 + - name: "Set up Julia" + uses: julia-actions/setup-julia@v1 with: - name: examples - path: examples/src/ - - - name: auto-commit + version: '1.10' + + - run: julia -e 'using Pkg; Pkg.add("PlutoSliderServer"); Pkg.add("FMI")' + - run: julia -e 'using PlutoSliderServer; PlutoSliderServer.export_directory("examples/pluto-src")' + + - name: "auto-commit (retry on merge)" + if: success() && github.event_name != 'pull_request' && github.branch == 'main' + uses: nick-fields/retry@v3 env: - CI_COMMIT_MESSAGE: Jupyter nbconvert synch - modified, paired .ipynb files + CI_COMMIT_MESSAGE: pluto-examples[${{ github.ref }}] CI_COMMIT_AUTHOR: github-actions[bot] - EXAMPLES_PATH: examples/src - # Fetch all and clear the stash list. Include all files from the examples/src folder to the stash and switch the branch. - # Reset the branch and remove all current files in the examples/src folder. + EXAMPLES_PATH: examples + # Fetch all and clear the stash list. Include all files from the examples folder to the stash and switch the branch. + # Reset the branch and remove all current files in the examples folder. # Checkout the last stash to restore the new notebooks and apply the stash index to restore all other new files in the folder. - run: | - git fetch --all - git stash clear - git stash --include-untracked -- ${{ env.EXAMPLES_PATH }} - git switch examples - git reset --hard origin/examples - rm -rf ${{ env.EXAMPLES_PATH }} - git checkout stash -f -- ${{ env.EXAMPLES_PATH }} - git stash apply --index - git stash drop - git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}" - git config --global user.email "${{ env.CI_COMMIT_AUTHOR }}@users.noreply.github.com" - git config --global core.autocrlf false - git add ${{ env.EXAMPLES_PATH }} - git commit -m "${{ env.CI_COMMIT_MESSAGE }}" - git push origin examples + with: + timeout_minutes: 999 + max_attempts: 10 + warning_on_retry: false + shell: bash + command: | + git fetch --all + git stash clear + git stash --include-untracked -- ${{ env.EXAMPLES_PATH }} + git switch examples + git reset --hard origin/examples + git checkout stash -f -- ${{ env.EXAMPLES_PATH }} + git stash apply --index + git stash drop + git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}" + git config --global user.email "${{ env.CI_COMMIT_AUTHOR }}@users.noreply.github.com" + git config --global core.autocrlf false + git pull + git add ${{ env.EXAMPLES_PATH }} + git commit -m "${{ env.CI_COMMIT_MESSAGE }}" + git push origin examples || (git reset --soft HEAD~1 && (exit 1)) call-docu: - needs: auto-commit - if: github.event_name != 'pull_request' + needs: [jypiter, pluto] + if: github.event_name != 'pull_request' && github.branch == 'main' runs-on: ubuntu-latest steps: # Trigger an repoisitory dispath event diff --git a/Project.toml b/Project.toml index 6d3844f6..21771692 100644 --- a/Project.toml +++ b/Project.toml @@ -1,25 +1,15 @@ name = "FMI" uuid = "14a09403-18e3-468f-ad8a-74f8dda2d9ac" authors = ["TT ", "LM ", "JK "] -version = "0.13.3" +version = "0.14.0" [deps] -DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa" -Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" FMIExport = "31b88311-cab6-44ed-ba9c-fe5a9abbd67a" FMIImport = "9fcbc62e-52a0-44e9-a616-1359a0008194" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" -Requires = "ae029012-a4dd-5104-9daa-d747884805df" -ThreadPools = "b189fb0b-2eb5-4ed4-bc0c-d34c51242431" [compat] -DifferentialEquations = "7.7.0 - 7.13" -Downloads = "1" -FMIExport = "0.3.0" -FMIImport = "0.16.0" +FMIExport = "0.4.0" +FMIImport = "1.0.0" LinearAlgebra = "1" -ProgressMeter = "1.7.0 - 1.9" -Requires = "1.3.0" -ThreadPools = "2.1.1" julia = "1.6" diff --git a/README.md b/README.md index 4f6e8a67..4b64338b 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,42 @@ # FMI.jl ## What is FMI.jl? -[*FMI.jl*](https://github.com/ThummeTo/FMI.jl) is a free-to-use software library for the Julia programming language which integrates the **F**unctional **M**ock-Up **I**nterface ([fmi-standard.org](https://fmi-standard.org/)): load or create, parameterize, differentiate, simulate and plot FMUs seamlessly inside the Julia programming language! +[*FMI.jl*](https://github.com/ThummeTo/FMI.jl) is a free-to-use software library for the Julia programming language which integrates the **F**unctional **M**ock-Up **I**nterface ([fmi-standard.org](https://fmi-standard.org/)): load or create, parameterize, differentiate, linearize, simulate and plot FMUs seamlessly inside the Julia programming language! -[![Dev Docs](https://img.shields.io/badge/docs-dev-blue.svg)](https://ThummeTo.github.io/FMI.jl/dev) -[![Test (latest)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLatest.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLatest.yml) -[![Test (LTS)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLTS.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLTS.yml) -[![FMI2 Cross Checks (latest)](https://github.com/ThummeTo/FMI.jl/actions/workflows/CrossChecks.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/CrossChecks.yml) -[![Examples (latest)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Example.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Example.yml) -[![Build Docs](https://github.com/ThummeTo/FMI.jl/actions/workflows/Documentation.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Documentation.yml) -[![Run PkgEval](https://github.com/ThummeTo/FMI.jl/actions/workflows/Eval.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Eval.yml) -[![Coverage](https://codecov.io/gh/ThummeTo/FMI.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ThummeTo/FMI.jl) -[![ColPrac: Contributor's Guide on Collaborative Practices for Community Packages](https://img.shields.io/badge/ColPrac-Contributor's%20Guide-blueviolet)](https://github.com/SciML/ColPrac) -[![FMI Downloads](https://shields.io/endpoint?url=https://pkgs.genieframework.com/api/v1/badge/FMI)](https://pkgs.genieframework.com?packages=FMI) -[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) +| | | +|---|---| +| Documentation | [![Build Docs](https://github.com/ThummeTo/FMI.jl/actions/workflows/Documentation.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Documentation.yml) [![Dev Docs](https://img.shields.io/badge/docs-dev-blue.svg)](https://thummeto.github.io/FMI.jl/dev/) | +| Examples | [![Examples (latest)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Example.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Example.yml) | +| Tests | [![Test (latest)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLatest.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLatest.yml) [![Test (LTS)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLTS.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/TestLTS.yml) [![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) | +| FMI cross checks| [![FMI2 Cross Checks](https://github.com/ThummeTo/FMI.jl/actions/workflows/CrossChecks.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/CrossChecks.yml) | +| Package evaluation| [![Run PkgEval](https://github.com/ThummeTo/FMI.jl/actions/workflows/Eval.yml/badge.svg)](https://github.com/ThummeTo/FMI.jl/actions/workflows/Eval.yml) | +| Code coverage | [![Coverage](https://codecov.io/gh/ThummeTo/FMI.jl/branch/main/graph/badge.svg)](https://app.codecov.io/gh/ThummeTo/FMI.jl) | +| Collaboration | [![ColPrac: Contributor's Guide on Collaborative Practices for Community Packages](https://img.shields.io/badge/ColPrac-Contributor's%20Guide-blueviolet)](https://github.com/SciML/ColPrac) | +## Breaking Changes in FMI.jl (starting from v0.14.0 until release of v1.0.0) +If you want to migrate your project from [*FMI.jl*](https://github.com/ThummeTo/FMI.jl) < v1.0.0 to >= v1.0.0, you will face some breaking changes - but they are worth it as you will see! We decided to do multiple smaller breaking changes starting with v0.14.0, instead of one big one. Some of them are already implemented (checked), some are still on the todo (unchecked) but will be implemented before releasing v1.0.0. + +- [x] Many functions, that are not part of the FMI-standard, had the prefix `fmi2...` or `fmi3...`. This was corrected. Now, only functions that are defined by the standard itself, like e.g. `fmi2Instantiate` are allowed to keep the prefix. Other methods, like `fmi2ValueReferenceToString`, that where added to make this library more comfortable, are now cleaned to be more the Julia way: `valueReferenceToString`. If your code errors, the corresponding function might have lost it's prefix, so try this first. + +- [x] Wrapper functions where removed, because that is not the Julia way. In most cases, this will not affect your code. + +- [x] [*FMICore.jl*](https://github.com/ThummeTo/FMICore.jl) and [*FMIImport.jl*](https://github.com/ThummeTo/FMIImport.jl) were divided into [*FMICore.jl*](https://github.com/ThummeTo/FMICore.jl), [*FMIImport.jl*](https://github.com/ThummeTo/FMIImport.jl) and [*FMIBase.jl*](https://github.com/ThummeTo/FMIBase.jl). [*FMICore.jl*](https://github.com/ThummeTo/FMICore.jl) now holds the pure standard definition (C-types and -functions), while [*FMIBase.jl*](https://github.com/ThummeTo/FMIBase.jl) holds everything that is needed on top of that in [*FMIImport.jl*](https://github.com/ThummeTo/FMIImport.jl) as well as in [*FMIExport.jl*](https://github.com/ThummeTo/FMIExport.jl). + +- [ ] Updated all library tests for a better code coverage. + +- [ ] We tried to document every function, if you find undocumented user-level functions, please open an issue or PR. + +- [ ] Allocations, type stability and code format where optimized and are monitored by CI now. + +- [ ] Dependencies are reduced a little, to make the libraries more light-weight. + +- [ ] RAM for allocated FMUs, their instances and states, is now auto-released. For maximum performance/safety you can use FMUs in blocks (like file reading/writing). + +- [ ] New low-level interfaces are introduced, that fit the SciML-ecosystem. For example, a FMU can still be simulated with `simulate(fmu)`, but one can also decide to create a `prob = FMUProblem(fmu)` (like an `ODEProblem`) and use `solve(prob)` to obtain a solution. Keywords will be adapted to have a fully consistent interface with the remaining SciML-ecosystem. + +- [ ] Optimization for new Julia LTS v1.10, removing code to keep downward compatibility with old LTS v1.6. + +πŸŽ‰ After all listed features are implemented, v1.0.0 will be released! πŸŽ‰ ## How can I use FMI.jl? 1\. Open a Julia-REPL, switch to package mode using `]`, activate your preferred environment. @@ -37,16 +59,16 @@ using FMI, Plots # load and instantiate a FMU -fmu = fmiLoad(pathToFMU) +fmu = loadFMU(pathToFMU) # simulate from t=0.0s until t=10.0s and record the FMU variable named "mass.s" -simData = fmiSimulate(fmu, (0.0, 10.0); recordValues=["mass.s"]) +simData = simulate(fmu, (0.0, 10.0); recordValues=["mass.s"]) # plot it! plot(simData) # free memory -fmiUnload(myFMU) +unloadFMU(myFMU) ``` ## What is currently supported in FMI.jl? @@ -57,21 +79,21 @@ fmiUnload(myFMU) | | **FMI2.0.3** | | **FMI3.0** | | **SSP1.0** | | |-----------------------------------|--------------|--------|------------|--------|------------|--------| | | Import | Export | Import | Export | Import | Export | -| CS | βœ”οΈβœ”οΈ | 🚧 | βœ”οΈ | πŸ“… | πŸ“… | πŸ“… | -| ME (continuous) | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | 🚧 | πŸ“… | πŸ“… | πŸ“… | -| ME (discontinuous) | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | 🚧 | πŸ“… | πŸ“… | πŸ“… | +| CS | βœ”οΈβœ”οΈ | 🚧 | βœ”οΈβœ”οΈ | πŸ“… | πŸ“… | πŸ“… | +| ME (continuous) | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | πŸ“… | πŸ“… | πŸ“… | +| ME (discontinuous) | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | πŸ“… | πŸ“… | πŸ“… | | SE | 🚫 | 🚫 | 🚧 | πŸ“… | 🚫 | 🚫 | -| Explicit solvers | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | βœ”οΈ | πŸ“… | πŸ“… | πŸ“… | -| Implicit solvers (autodiff=false) | βœ”οΈβœ”οΈ | 🚧 | βœ”οΈ | πŸ“… | πŸ“… | πŸ“… | -| Implicit solvers (autodiff=true) | βœ”οΈβœ”οΈ | 🚧 | 🚧 | πŸ“… | πŸ“… | πŸ“… | -| get/setState | βœ”οΈβœ”οΈ | πŸ“… | βœ”οΈ | πŸ“… | 🚫 | 🚫 | -| getDirectionalDerivatives | βœ”οΈβœ”οΈ | πŸ“… | βœ”οΈ | πŸ“… | 🚫 | 🚫 | -| getAdjointDerivatives | 🚫 | 🚫 | βœ”οΈ | πŸ“… | 🚫 | 🚫 | +| Explicit solvers | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | πŸ“… | πŸ“… | πŸ“… | +| Implicit solvers (autodiff=false) | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | βœ”οΈβœ”οΈ | πŸ“… | πŸ“… | πŸ“… | +| Implicit solvers (autodiff=true) | βœ”οΈ | βœ”οΈβœ”οΈ | βœ”οΈ | πŸ“… | πŸ“… | πŸ“… | +| get/setState | βœ”οΈβœ”οΈ | πŸ“… | βœ”οΈβœ”οΈ | πŸ“… | 🚫 | 🚫 | +| getDirectionalDerivatives | βœ”οΈβœ”οΈ | πŸ“… | βœ”οΈβœ”οΈ | πŸ“… | 🚫 | 🚫 | +| getAdjointDerivatives | 🚫 | 🚫 | βœ”οΈβœ”οΈ | πŸ“… | 🚫 | 🚫 | | FMI Cross Checks | βœ”οΈβœ”οΈ | πŸ“… | πŸ“… | πŸ“… | 🚫 | 🚫 | -βœ”οΈβœ”οΈ supported & tested +βœ”οΈβœ”οΈ supported & CI-tested -βœ”οΈ beta supported (implemented), but untested +βœ”οΈ beta supported: implemented, but not CI-tested 🚧 work in progress @@ -87,6 +109,7 @@ To keep dependencies nice and clean, the original package [*FMI.jl*](https://git - [*FMI.jl*](https://github.com/ThummeTo/FMI.jl): High level loading, manipulating, saving or building entire FMUs from scratch - [*FMIImport.jl*](https://github.com/ThummeTo/FMIImport.jl): Importing FMUs into Julia - [*FMIExport.jl*](https://github.com/ThummeTo/FMIExport.jl): Exporting stand-alone FMUs from Julia Code +- [*FMIBase.jl*](https://github.com/ThummeTo/FMIBase.jl): Common concepts for import and export of FMUs - [*FMICore.jl*](https://github.com/ThummeTo/FMICore.jl): C-code wrapper for the FMI-standard - [*FMISensitivity.jl*](https://github.com/ThummeTo/FMISensitivity.jl): Static and dynamic sensitivities over FMUs - [*FMIBuild.jl*](https://github.com/ThummeTo/FMIBuild.jl): Compiler/Compilation dependencies for FMIExport.jl @@ -94,7 +117,7 @@ To keep dependencies nice and clean, the original package [*FMI.jl*](https://git - [*FMIZoo.jl*](https://github.com/ThummeTo/FMIZoo.jl): A collection of testing and example FMUs ## What Platforms are supported? -[*FMI.jl*](https://github.com/ThummeTo/FMI.jl) is tested (and testing) under Julia Versions *1.6 LTS* (64-bit) and *latest* (64-bit) on Windows *latest* (64-bit) and Ubuntu *latest* (64-bit). Mac and Julia (32-bit) should work, but untested. For the best performance, we recommend using Julia >= 1.7. +[*FMI.jl*](https://github.com/ThummeTo/FMI.jl) is tested (and testing) under Julia Versions *1.6 LTS* (64-bit) and *latest* (64-bit) on Windows *latest* (64-bit, 32-bit) and Ubuntu *latest* (64-bit). Mac (64-bit, 32-bit) and Ubuntu (32-bit) should work, but untested. For the best performance, we recommend using Julia >= 1.7, even if we support and test for the official LTS (1.6.7). ## How to cite? Tobias Thummerer, Lars Mikelsons and Josef Kircher. 2021. **NeuralFMU: towards structural integration of FMUs into neural networks.** Martin SjΓΆlund, Lena Buffoni, Adrian Pop and Lennart Ochel (Ed.). Proceedings of 14th Modelica Conference 2021, LinkΓΆping, Sweden, September 20-24, 2021. LinkΓΆping University Electronic Press, LinkΓΆping (LinkΓΆping Electronic Conference Proceedings ; 181), 297-306. [DOI: 10.3384/ecp21181297](https://doi.org/10.3384/ecp21181297) @@ -109,7 +132,4 @@ Contributors are welcome. Before contributing, please read, understand and follo During development of new implementations or optimizations on exisitng code, one will have to make design decissions that influence the library performance and usability. The following priorization should be the basis for decision-making: - **#1 Compliance with standard:** It is the highest priority to be compliant with the FMI standard ([fmi-standard.org](https://fmi-standard.org/)). Identifiers described in the standard must be used. Topologies should follow the specification as far as the possibilities of the Julia programming language allows. - **#2 Performance:** Because [*FMI.jl*](https://github.com/ThummeTo/FMI.jl) is a simulation tool, performance is very important. This applies to the efficient use of CPU and GPU, but also the conscientious use of RAM and disc space. -- **#3 Usability:** The library should be as usable as possible, as long as being fully compliant with the FMI standard. - -## Interested in Hybrid Modelling in Julia using FMUs? -See [*FMIFlux.jl*](https://github.com/ThummeTo/FMIFlux.jl). +- **#3 Usability:** The library should be as usable as possible and feel "the Julia way" (e.g. by using multiple dispatch instead of the "C coding style"), as long as being fully compliant with the FMI standard. diff --git a/cross_checks/cross_check.jl b/cross_checks/cross_check.jl index b9dbe710..3c71e758 100644 --- a/cross_checks/cross_check.jl +++ b/cross_checks/cross_check.jl @@ -76,7 +76,7 @@ function runCrossCheckFmu(checkPath::String, resultPath::String, check::FmuCross fmuToCheck = nothing try if !(check.notCompliant && skipnotcompliant) - fmuToCheck = fmiLoad(pathToFMU) + fmuToCheck = loadFMU(pathToFMU) fmiInfo(fmuToCheck) hasInputValues = false @@ -107,17 +107,17 @@ function runCrossCheckFmu(checkPath::String, resultPath::String, check::FmuCross if hasInputValues if check.type == CS - simData = fmiSimulateCS(fmuToCheck, (tStart, tStop); tolerance=relTol, saveat=fmuRefValues[1], inputFunction=getInputValues, inputValueReferences=:inputs, recordValues=fmuRecordValueNames) + simData = simulateCS(fmuToCheck, (tStart, tStop); tolerance=relTol, saveat=fmuRefValues[1], inputFunction=getInputValues, inputValueReferences=:inputs, recordValues=fmuRecordValueNames) elseif check.type == ME - simData = fmiSimulateME(fmuToCheck, (tStart, tStop); reltol=relTol, saveat=fmuRefValues[1], inputFunction=getInputValues, inputValueReferences=:inputs, recordValues=fmuRecordValueNames) + simData = simulateME(fmuToCheck, (tStart, tStop); reltol=relTol, saveat=fmuRefValues[1], inputFunction=getInputValues, inputValueReferences=:inputs, recordValues=fmuRecordValueNames) else @error "Unkown FMU Type. Only 'cs' and 'me' are valid types" end else if check.type == CS - simData = fmiSimulateCS(fmuToCheck, (tStart, tStop); tolerance=relTol, saveat=fmuRefValues[1], recordValues=fmuRecordValueNames) + simData = simulateCS(fmuToCheck, (tStart, tStop); tolerance=relTol, saveat=fmuRefValues[1], recordValues=fmuRecordValueNames) elseif check.type == ME - simData = fmiSimulateME(fmuToCheck, (tStart, tStop); reltol=relTol, saveat=fmuRefValues[1], recordValues=fmuRecordValueNames) + simData = simulateME(fmuToCheck, (tStart, tStop); reltol=relTol, saveat=fmuRefValues[1], recordValues=fmuRecordValueNames) else @error "Unkown FMU Type. Only 'cs' and 'me' are valid types" end @@ -179,7 +179,7 @@ function runCrossCheckFmu(checkPath::String, resultPath::String, check::FmuCross end finally try - fmiUnload(fmuToCheck) + unloadFMU(fmuToCheck) catch end end diff --git a/cross_checks/cross_check_config.jl b/cross_checks/cross_check_config.jl index 63007057..1cd1d9b8 100644 --- a/cross_checks/cross_check_config.jl +++ b/cross_checks/cross_check_config.jl @@ -9,40 +9,7 @@ const TOOL_VERSION = "0.9.2" const FMI_CROSS_CHECK_REPO_NAME = "fmi-cross-check" const NRMSE_THRESHHOLD = 5 const EXCLUDED_SYSTEMS = ["AMESim", "Test-FMUs", "SimulationX", "Silver"] -const CROSS_CHECK_README_CONTENT = -"# FMI.jl - -## How can I use FMI.jl? -1\\. Open a Julia-REPL, switch to package mode using `]`, activate your preferred environment.\n - -2\\. Install [*FMI.jl*](https://github.com/ThummeTo/FMI.jl):\n -```julia-repl -(@v1.6) pkg> add FMI -``` - -3\\. If you want to check that everything works correctly, you can run the tests bundled with [*FMI.jl*](https://github.com/ThummeTo/FMI.jl):\n -```julia-repl -(@v1.6) pkg> test FMI -``` - -4\\. Have a look inside the [examples folder](https://github.com/ThummeTo/FMI.jl/tree/examples/examples) in the examples branch or the [examples section](https://thummeto.github.io/FMI.jl/dev/examples/overview/) of the documentation. All examples are available as Julia-Script (*.jl*), Jupyter-Notebook (*.ipynb*) and Markdown (*.md*). - -## How can I simulate a FMU and plot values? -```julia -using FMI, Plots - -# load and instantiate a FMU -myFMU = fmiLoad(pathToFMU) - -# simulate from t=0.0s until t=10.0s and record the FMU variable named 'mass.s' -simData = fmiSimulate(myFMU, 0.0, 10.0; recordValues=['mass.s']) - -# plot it! -fmiPlot(simData) - -# free memory -fmiUnload(myFMU) -```" +const CROSS_CHECK_README_CONTENT = "See https://github.com/ThummeTo/FMI.jl for more information." #static strings const ME = "me" diff --git a/cross_checks/cross_check_lib.jl b/cross_checks/cross_check_lib.jl index 726fcc01..7f17376f 100644 --- a/cross_checks/cross_check_lib.jl +++ b/cross_checks/cross_check_lib.jl @@ -78,12 +78,12 @@ Calculate the mean of all normalized root mean square errors for the different v It is normalized to the difference between the smallest and largest values of the respective variable # Arguments - `recordedVariables::Vector{String}`: List of all variable names that were recorded within the FMU simulation -- `simData::FMU2Solution`: The solution data of the FMU (returned values of fmiSimulate()) +- `simData::FMUSolution`: The solution data of the FMU (returned values of fmiSimulate()) - `referenceData::Table`: Reference data that was provided with the cross check FMU that is used as basis for the error calculation # Returns - `nrmse::Float64`: the mean of the nrmse of all recorded variables """ -function calucateNRMSE(recordedVariables::Vector{String}, simData::FMU2Solution, referenceData)::Float64 +function calucateNRMSE(recordedVariables::Vector{String}, simData::FMUSolution, referenceData)::Float64 squaredErrorSums = zeros(length(recordedVariables)) valueCount = zeros(length(recordedVariables)) minimalValues = [] diff --git a/docs/Project.toml b/docs/Project.toml index 71ee3c6b..7d97ca60 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -2,6 +2,7 @@ CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +FMIBase = "900ee838-d029-460e-b485-d98a826ceef2" FMICore = "8af89139-c281-408e-bce2-3005eb87462f" FMIImport = "9fcbc62e-52a0-44e9-a616-1359a0008194" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" diff --git a/docs/make.jl b/docs/make.jl index f00ca742..777c4d27 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -4,7 +4,7 @@ # import Pkg; Pkg.develop(path=joinpath(@__DIR__,"../../FMI.jl")) -using Documenter, Plots, JLD2, DataFrames, CSV, MAT, FMI, FMIImport, FMICore +using Documenter, Plots, JLD2, DataFrames, CSV, MAT, FMI, FMIBase, FMIImport, FMICore using Documenter: GitHubActions makedocs(sitename="FMI.jl", @@ -15,10 +15,10 @@ makedocs(sitename="FMI.jl", size_threshold = 512000, size_threshold_ignore = ["deprecated.md"] ), - modules = [FMI, FMIImport, FMICore], + modules = [FMI, FMIImport, FMICore, FMIBase], checkdocs=:exports, linkcheck=true, - linkcheck_ignore=["https://thummeto.github.io/FMI.jl/dev/examples/inputs/", "https://github.com/ThummeTo/FMICore.jl/blob/main/src/FMI2_c.jl#L718"], + #linkcheck_ignore=["https://thummeto.github.io/FMI.jl/dev/examples/inputs/", "https://github.com/ThummeTo/FMICore.jl/blob/main/src/FMI2_c.jl#L718"], pages= Any[ "Introduction" => "index.md" "Features" => "features.md" @@ -32,16 +32,16 @@ makedocs(sitename="FMI.jl", "Manipulation" => "examples/manipulation.md" "Multithreading" => "examples/multithreading.md" "Multiprocessing" => "examples/multiprocessing.md" + "Pluto Workshops" => "examples/workshops.md" ] "User Level API - FMI.jl" => "library.md" "Developer Level API" => Any[ "fmi version independent content" => Any[ - "fmi_lowlevel_library_types.md", "fmi_lowlevel_library_constants.md", + "fmi_lowlevel_modeldescription_functions.md", "fmi_lowlevel_library_functions.md" ], "FMI2 specific content" => Any[ - "fmi2_lowlevel_library_types.md", "fmi2_lowlevel_library_constants.md", "FMI2 Functions in FMI Import/Core .jl" => Any[ "fmi2_lowlevel_modeldescription_functions.md", @@ -51,7 +51,6 @@ makedocs(sitename="FMI.jl", ] ], "FMI3 specific content" => Any[ - "fmi3_lowlevel_library_types.md", "fmi3_lowlevel_library_constants.md", "FMI3 Functions in FMI Import/Core .jl" => Any[ "fmi3_lowlevel_modeldescription_functions.md", diff --git a/docs/src/assets/FMI_JL_family.pdf b/docs/src/assets/FMI_JL_family.pdf index 338448d3..bf38dd10 100644 Binary files a/docs/src/assets/FMI_JL_family.pdf and b/docs/src/assets/FMI_JL_family.pdf differ diff --git a/docs/src/assets/FMI_JL_family.png b/docs/src/assets/FMI_JL_family.png index 5e81fd6e..e4e58a13 100644 Binary files a/docs/src/assets/FMI_JL_family.png and b/docs/src/assets/FMI_JL_family.png differ diff --git a/docs/src/deprecated.md b/docs/src/deprecated.md index 0ca063a4..df4ee2de 100644 --- a/docs/src/deprecated.md +++ b/docs/src/deprecated.md @@ -4,53 +4,11 @@ this doc page is necessary as all exported functions must be documented in the m ### internal functions: remove export? ```@docs -fmi2CallbackLogger -fmi2CallbackAllocateMemory -fmi2CallbackFreeMemory -fmi3CallbackLogger fmi2CallbackFunctions -fmi2CallbackStepFinished ``` ### deprecated Mostly wrappers that are not supposed to be used (call specific wrapped functions instead) ```@docs -fmiSetReal -fmiReset -fmiGetGenerationTool -fmiEnterContinuousTimeMode -fmiGetEventIndicators -fmiSetBoolean -fmiFreeInstance! -fmiInstantiate! -fmiTerminate -fmiDoStep -fmiSetInteger -fmiCompletedIntegratorStep -fmiExitInitializationMode -fmiSetupExperiment -fmiSetDebugLogging -fmiSerializedFMUstateSize -fmiSerializeFMUstate -fmiDeSerializeFMUstate -fmiEnterInitializationMode -fmiGetDirectionalDerivative! -fmiNewDiscreteStates -fmiGetDirectionalDerivative -fmiSetRealInputDerivatives -fmiGetGenerationDateAndTime -fmiGetContinuousStates -fmiSetContinuousStates -fmiGetNominalsOfContinuousStates -fmiSetTime -fmiSetString -fmiGetString -fmiGetString! -fmiGetInteger -fmiGetInteger! -fmiGetReal -fmiGetReal! -fmiGetBoolean -fmiGetBoolean! ``` diff --git a/docs/src/examples/overview.md b/docs/src/examples/overview.md index e9443e33..8066db28 100644 --- a/docs/src/examples/overview.md +++ b/docs/src/examples/overview.md @@ -10,7 +10,6 @@ Examples are subdevided into *Basics*, *Advanced* and *Publication appendices*. - [__Simulate__](https://thummeto.github.io/FMI.jl/dev/examples/simulate/): Showing how you can simulate a CS-FMU and a ME-FMU. - [__Parameterize__](https://thummeto.github.io/FMI.jl/dev/examples/parameterize/): A short example explaining how to parameterize a FMU before simulation. -- [__Inputs__](https://thummeto.github.io/FMI.jl/dev/examples/inputs/): A short example explaining how to simulate a FMU with inputs. **Advanced examples:** diff --git a/docs/src/examples/workshops.md b/docs/src/examples/workshops.md new file mode 100644 index 00000000..2cccd08a --- /dev/null +++ b/docs/src/examples/workshops.md @@ -0,0 +1,4 @@ +[Pluto](https://plutojl.org/) based notebooks, that can easyly be executed on your own Pluto-Setup. +```@raw html + +``` \ No newline at end of file diff --git a/docs/src/features.md b/docs/src/features.md index e96b08a2..d3813c28 100644 --- a/docs/src/features.md +++ b/docs/src/features.md @@ -1,53 +1,55 @@ # Features Please note, that this guide focuses also on users, that are not familiar with FMI. The following feature explanations are written in an easy-to-read-fashion, so there might be some points that are scientifically only 95% correct. For further information on FMI and FMUs, see [fmi-standard.org](https://fmi-standard.org/). +The term `fmiX...` refers to a value or function that is available along different versions of FMI, for example `fmiXValueReference` is a wildcard for `fmi2ValueReference` and `fmi3ValueReference`. ## Execution Configuration Not all FMUs support all features they should according to the FMI-standard, so *FMI.jl* provides a so called *execution configuration*. This configuration is also respected by *FMIFlux.jl*. The content of the execution configuration may change in future (together with new or deprecated features of linked libraries), but the most important core features will be kept over time. Because not all users need the full potential of this configuration tool, there are three presets given: -- `myFMU.executionConfig = FMU2_EXECUTION_CONFIGURATION_NO_RESET` is the default operation mode for FMUs. FMUs are not reset via `fmi2Reset`, but new instantiated for every simulation run (or training step). This is not the most efficient way, but many FMUs have problems with resetting. -- `myFMU.executionConfig = FMU2_EXECUTION_CONFIGURATION_RESET` is faster for well-implemented FMUs, but needs a fully working `fmi2Reset`-function. So if you know you have a fully working `fmi2Reset`, you may be faster with that option. -- `myFMU.executionConfig = FMU2_EXECUTION_CONFIGURATION_NO_FREEING` should only be the very last choice. If your FMU neither supports `fmi2Reset` nor a proper `fmi2FreeInstance`, you could use this configuration as a last way out. Keep in mind, that new FMU instances are allocated but not freed, as long as your Julia instance is running (memory leak). In general, the amount of leaked memory is small, but you need to know what you are doing, if you do thousands or ten-thousands of simulation runs with such a FMU. -- `myFMU.executionConfig = FMU2_EXECUTION_CONFIGURATION_NOTHING` should be used if you want maximum control over what is done and what not. This means you need to take care of instantiating, initialization, setting up and releasing FMU instances by yourself. +- `myFMU.executionConfig = FMU_EXECUTION_CONFIGURATION_NO_RESET` is the default operation mode for FMUs. FMUs are not reset via `fmi2Reset`, but new instantiated for every simulation run (or training step). This is not the most efficient way, but many FMUs have problems with resetting. +- `myFMU.executionConfig = FMU_EXECUTION_CONFIGURATION_RESET` is faster for well-implemented FMUs, but needs a fully working `fmi2Reset`-function. So if you know you have a fully working `fmi2Reset`, you may be faster with that option. +- `myFMU.executionConfig = FMU_EXECUTION_CONFIGURATION_NO_FREEING` should only be the very last choice. If your FMU neither supports `fmi2Reset` nor a proper `fmi2FreeInstance`, you could use this configuration as a last way out. Keep in mind, that new FMU instances are allocated but not freed, as long as your Julia instance is running (memory leak). In general, the amount of leaked memory is small, but you need to know what you are doing, if you do thousands or ten-thousands of simulation runs with such a FMU. +- `myFMU.executionConfig = FMU_EXECUTION_CONFIGURATION_NOTHING` should be used if you want maximum control over what is done and what not. This means you need to take care of instantiating, initialization, setting up and releasing FMU instances by yourself. +For a more detailed overview, please see the `?FMUExecutionConfig`. ## Debugging / Logging ### Logging FMI-calls -To log all FMI-calls that happen (including "hidden" calls e.g. if you are using `fmiSimulate`) you can enable debugging for *FMICore.jl* using `ENV["JULIA_DEBUG"] = "FMICore"`. This will log any `fmi2xxx`-call, including the given parameters and return value. +To log all FMI-calls that happen (including "hidden" calls e.g. if you are using `simulate`) you can enable debugging for *FMICore.jl* using `ENV["JULIA_DEBUG"] = "FMICore"`. This will log any `fmi2xxx`- and `fmi3xxx`-call, including the given parameters and return value. This can be *a lot* of calls, so you may want to redirect your REPL output to file. ### Printing internal FMU messages -Many FMUs support for printing debugging messages. To force message printing, you can use the keyword `logginOn=true` either ... +Many FMUs support for printing debugging messages. To force message printing, you can use the keyword `loggingOn=true` either ... - in the call `fmiInstantiate`, for example `fmiInstantiate(myFMU; loggingOn=true)` or - as part of the `executionConfig`, for example `myFMU.executionConfig.loggingOn=true` You can further control which message types - like `OK`, `Warning`, `Discard`, `Error`, `Fatal`, `Pending` - should be logged by using the keywords `logStatus{TYPE}=true` as part of `fmiInstantiate` or (soon) the execution configuration. By default, all are activated. -If the FMU uses a variadic callback function for messages (this is not supported by Julia at this time), you may need to activate external callbacks with the keyword `externalCallbacks=true` either ... +If your FMU (for FMI2 only, FMI3 changed this) uses a variadic callback function for messages (this is not supported by Julia at this time), you may need to activate external callbacks with the keyword `externalCallbacks=true` either ... - in the call `fmiInstantiate!`, for example `fmiInstantiate!(myFMU; loggingOn=true, externalCallbacks=true)` or - as part of the `executionConfig`, for example `myFMU.executionConfig.loggingOn=true; myFMU.executionConfig.externalCallbacks=true` -Note, that external callbacks are currently only supported on Windows. +External callbacks are currently only supported on Windows and Linux. ## Model variable identification *FMI.jl* offers multiple ways to retrieve your model variables. Any function that accepts a variable identifier can handle the following argument types: -- `UInt32` or `fmi2ValueReference` for example `1610612742` or `0x16000001`: This is the most performant way of passing a variable identifier, but you need to know the *value reference* (you can determine them by having a look in the `modelDescription.xml`). -- `Array{UInt32}` or `Array{fmi2ValueReference}` for example `[1610612742, 1610612743]` or `[0x16000001, 0x16000002]`: This is the most performant way of passing multiple variable identifiers, but you need to know the *value references*. +- `UInt32` or `fmiXValueReference` for example `1610612742` or `0x16000001`: This is the most performant way of passing a variable identifier, but you need to know the *value reference* (you can determine them by having a look in the `modelDescription.xml`). +- `Vector{UInt32}` or `Vector{fmiXValueReference}` for example `[1610612742, 1610612743]` or `[0x16000001, 0x16000002]`: This is the most performant way of passing multiple variable identifiers, but you need to know the *value references*. - `String` for example `"ball.s"`: This is the most intuitive way, because you might already know the variable name from your modelling environment or model documentation. -- `Array{String}` for example `["ball.s", "der(ball.s)"]`: This is the most intuitive way for multiple variable identifiers, because you might already know the variable names from your modelling environment or model documentation. +- `Vector{String}` for example `["ball.s", "der(ball.s)"]`: This is the most intuitive way for multiple variable identifiers, because you might already know the variable names from your modelling environment or model documentation. - `Symbol` for example `:states`: There are multiple symbol-wildcards for interesting variable groups like `:all`, `:none`, `:states`, `:derivatives`, `:inputs` and `:outputs`. - `nothing`: If you don't want to record anything (same as `:none`) ## Event handling -In FMI2, there are basically two types of events: state and time. +In FMI, there are basically two types of events: state and time. State events are triggered, as soon as one or more *event indicators* - scalar values that describe the "distance" in state space to the next state event - crossing zero. Time events are triggered at known time points during the simulation. If your model has state and/or time events is detected automatically by *FMI.jl* and the event handling happens automatically in the background. -## Model exchange (ME) and co-simulation (CS) -There are two different model types for FMUs in FMI2: Model exchange (ME) and co-simulation (CS). -If you have a FMU and are only interested in getting it simulated, use `fmiSimulate` so *FMI.jl* will automatically pick CS if available and otherwise ME. -If you want to force a specific simulation mode, you can use `fmiSimulateME` (for ME) or `fmiSimulateCS` (for CS). +## Model exchange, co-simulation and scheduled execution +There are two different model types for FMUs in FMI2: Model exchange (ME) and co-simulation (CS). FMI3 further adds the mode scheduled execution (SE). +If you have a FMU and are only interested in getting it simulated, use `simulate` so *FMI.jl* will automatically pick CS if available and otherwise ME. +If you want to force a specific simulation mode, you can use `simulateME` (for ME), `simulateCS` (for CS) or `simulateSE` (for SE). ## Simulate arbitrary time intervals -You can simply simulate arbitrary time intervals by passing a `startTime` unequal zero to `fmi2SetupExperiment`. -Because many FMUs don't support `startTime != 0.0` and will throw an error or warning, a time shifting feature inside *FMI.jl* can be used, that performs all necessary steps in the background - corresponding commands like e.g. `fmi2SetTime` or `fmi2NewDiscreteStates` act like the desired time interval is simulated. +You can simply simulate arbitrary time intervals by passing a `startTime` unequal zero to `fmi2SetupExperiment` or [ToDo: corresponding FMI3 function]. +Because some FMUs don't support `startTime != 0.0` and will throw an error or warning, a time shifting feature inside *FMI.jl* can be used, that performs all necessary steps in the background - corresponding commands like e.g. `fmi2SetTime` or `fmi2NewDiscreteStates` act like the desired time interval is simulated. This feature is disabled by default, but can be activated in the execution configuration using `myFMU.executionConfig.autoTimeShift=true` while providing a `startTime != 0.0`. ## Performance @@ -60,13 +62,13 @@ Of course, you have to use the same piece of memory (to write your return values **Views:** You can use [array-views](https://docs.julialang.org/en/v1/base/arrays/#Views-(SubArrays-and-other-view-types)) instead of array-slices as input for in-place-functions, which further reduces memory allocations. -## AD-Ecosystem (Differentiation over FMUs) -Sensitivities over FMUs are fully integrated into *FMI.jl*, *FMIImport.jl* and *FMIFlux.jl*. Supported are *ForwardDiff.jl* together with all AD-frameworks, that use the interface of *ChainRules.jl* like e.g. *Zygote.jl*. As a result, you can use implicit solvers or you can use FMUs as part of machine learning applications. +## AD-Ecosystem (differentiation over FMUs) +Sensitivites over FMUs are fully integrated into *FMI.jl*, *FMIImport.jl* and *FMIFlux.jl*. Supported are *ForwardDiff.jl* together with all AD-frameworks, that use the interface of *ChainRules.jl* like e.g. *Zygote.jl* and *ReverseDiff.jl*. As a result, you can use implicit solvers or you can use FMUs as part of machine learning applications. ## Watch your progress -When simulating FMUs with *FMI.jl*, a progress meter is shown per default. You can control the appearance via the keyword argument `showProgress` for `fmiSimulate`, `fmiSimulateME` and `fmiSimulateCS`. +When simulating FMUs with *FMI.jl*, a progress meter is shown per default. You can control the appearance via the keyword argument `showProgress` for `simulate`, `simulateME`, `simulateCS` and `simulateSE`. Progress meters are also available for *FMIFlux.jl*, but deactivated by default (during training, this can be a bit too much). When evaluating a NeuralFMU, you can use the same keyword with `showProgress=true` to show a progress bar during training, too. -The simulation trajectory (also called the *solution* of your FMU's ODE system) can be plotted using `fmiPlot(myFMU, solution)`, all axis will be labeled automatically. +The simulation trajectory (also called the *solution* of your FMU's ODE system) can be plotted using `plot(solution)`, all axis will be labeled automatically. ## Parallelization -A native integrated support for multi-threaded and multi-process FMU-simulation will be deployed soon. \ No newline at end of file +A native integrated support for multi-threaded and multi-process FMU-simulation (for example for Monte Carlo experiments) will be deployed soon. \ No newline at end of file diff --git a/docs/src/fmi-tool-info.md b/docs/src/fmi-tool-info.md index 9a3b4eb3..85fd3f38 100644 --- a/docs/src/fmi-tool-info.md +++ b/docs/src/fmi-tool-info.md @@ -27,5 +27,5 @@ Detailed export information and automatically generated FMUs will be deployed so | NeuralFMU | [ME](https://github.com/ThummeTo/FMIExport.jl/tree/main/examples/FMI2/NeuralFMU) | coming soon | ## Validation tools -- [Dassault Dymola 2022X](https://www.3ds.com/de/produkte-und-services/catia/produkte/dymola/) +- [Dassault Dymola 2022X](https://www.3ds.com/products/catia/dymola) - [FMU Check](https://fmu-check.herokuapp.com/) \ No newline at end of file diff --git a/docs/src/fmi2_lowlevel_CS_functions.md b/docs/src/fmi2_lowlevel_CS_functions.md index 2523672b..bab699d4 100644 --- a/docs/src/fmi2_lowlevel_CS_functions.md +++ b/docs/src/fmi2_lowlevel_CS_functions.md @@ -26,6 +26,7 @@ fmi2CancelStep Status information is retrieved from the slave by the following functions: ```@docs +fmi2GetStatus fmi2GetStatus! fmi2GetRealStatus! fmi2GetIntegerStatus! diff --git a/docs/src/fmi2_lowlevel_library_constants.md b/docs/src/fmi2_lowlevel_library_constants.md index c1a79d37..046d51ba 100644 --- a/docs/src/fmi2_lowlevel_library_constants.md +++ b/docs/src/fmi2_lowlevel_library_constants.md @@ -1,12 +1,53 @@ +# FMI2 Types in FMI Import/Core .jl + +```@docs +FMU2 +FMU2Component +FMU2ComponentEnvironment +FMI2Struct +fmi2Initial +fmi2ScalarVariable +fmi2SimpleType +fmi2Type +fmi2BaseUnit +fmi2Unit +fmi2DisplayUnit +fmi2Char +fmi2Variability +fmi2VariableDependency +fmi2DependencyKind +fmi2EventInfo +fmi2Status +fmi2Annotation +fmi2ModelDescription +fmi2FMUstate +fmi2StatusKind +fmi2VariableNamingConvention +fmi2Causality +fmi2ComponentState +``` +fmi2StructMD +FMU2Solution +FMIImport.fmi2ValueReferenceFormat +FMU2Event +FMU2ExecutionConfiguration + # FMI2 Constants in FMI Import/Core .jl ```@docs fmi2True +fmi2ComponentStateInstantiated +fmi2ComponentStateInitializationMode +fmi2ComponentStateEventMode +fmi2ComponentStateContinuousTimeMode +fmi2ComponentStateTerminated +fmi2ComponentStateError +fmi2ComponentStateFatal +``` fmi2False fmi2StatusOK fmi2StatusWarning fmi2StatusPending fmi2StatusError fmi2StatusDiscard -fmi2StatusFatal -``` \ No newline at end of file +fmi2StatusFatal \ No newline at end of file diff --git a/docs/src/fmi2_lowlevel_library_functions.md b/docs/src/fmi2_lowlevel_library_functions.md index d3feb5dc..548764fc 100644 --- a/docs/src/fmi2_lowlevel_library_functions.md +++ b/docs/src/fmi2_lowlevel_library_functions.md @@ -5,18 +5,18 @@ platform dependent header file, several access functions, as well as the schema ## Opening and closing FMUs ```@docs +``` fmi2Unzip fmi2Load fmi2Reload fmi2Unload -``` ## Creation, Destruction and Logging of FMU Instances ```@docs fmi2Instantiate! fmi2Instantiate -fmi2FreeInstance! +fmi2FreeInstance fmi2SetDebugLogging ``` @@ -39,9 +39,6 @@ have identical values but other parts of the variable definition might be differ attributes). ```@docs -fmi2Get -fmi2Get! -fmi2Set fmi2GetReal fmi2GetReal! fmi2GetInteger @@ -55,6 +52,9 @@ fmi2SetInteger fmi2SetBoolean fmi2SetString ``` +fmi2Get +fmi2Get! +fmi2Set ## Getting and Setting the Complete FMU State The FMU has an internal state consisting of all values that are needed to continue a simulation. This internal state consists especially of the values of the continuous-time states, iteration variables, parameter values, input values, delay buffers, file identifiers, and FMU internal status information. With the functions of this section, the internal FMU state can be copied and the pointer to this copy is returned to the environment. The FMU state copy can be set as actual FMU state, in order to continue the simulation from it. @@ -63,7 +63,7 @@ The FMU has an internal state consisting of all values that are needed to contin fmi2GetFMUstate fmi2GetFMUstate! fmi2SetFMUstate -fmi2FreeFMUstate! +fmi2FreeFMUstate fmi2SerializedFMUstateSize fmi2SerializedFMUstateSize! fmi2SerializeFMUstate @@ -83,44 +83,29 @@ fmi2GetDirectionalDerivative fmi2GetDirectionalDerivative! fmi2SetRealInputDerivatives fmi2GetRealOutputDerivatives! +``` fmi2SampleJacobian fmi2SampleJacobian! -``` ## Conversion functions ```@docs -fmi2StringToValueReference -fmi2ValueReferenceToString -fmi2StringToCausality -fmi2CausalityToString -fmi2StringToVariability -fmi2VariabilityToString - -fmi2StatusToString -fmi2StringToDependencyKind -fmi2DependencyKindToString -fmi2StringToInitial -fmi2InitialToString ``` ## External/Additional functions ```@docs +setDiscreteStates +getDiscreteStates +getDiscreteStates! +getSimpleTypeAttributeStruct +getDeclaredType +``` fmi2GetSolutionDerivative fmi2GetSolutionState fmi2GetSolutionValue fmi2GetSolutionTime -fmi2ModelVariablesForValueReference -getCurrentComponent -hasCurrentComponent fmi2GetJacobian fmi2GetJacobian! fmi2GetFullJacobian fmi2GetFullJacobian! -fmi2GetStartValue -fmi2GetUnit -fmi2GetDeclaredType -fmi2GetInitial -fmi2GetSimpleTypeAttributeStruct -``` diff --git a/docs/src/fmi2_lowlevel_library_types.md b/docs/src/fmi2_lowlevel_library_types.md deleted file mode 100644 index b4cbc963..00000000 --- a/docs/src/fmi2_lowlevel_library_types.md +++ /dev/null @@ -1,30 +0,0 @@ -# FMI2 Types in FMI Import/Core .jl - -```@docs -FMU2 -FMU2Component -FMU2ComponentEnvironment -FMU2InputFunction -fmi2Struct -fmi2StructMD -fmi2Initial -FMU2Solution -fmi2ScalarVariable -fmi2SimpleType -fmi2Type -fmi2Unit -fmi2Char -FMIImport.fmi2ValueReferenceFormat -fmi2Variability -fmi2VariableDependency -fmi2DependencyKind -fmi2EventInfo -FMU2Event -FMU2ExecutionConfiguration -fmi2Status -fmi2Annotation -fmi2ModelDescription -fmi2FMUstate -fmi2StatusKind -fmi2Causality -``` \ No newline at end of file diff --git a/docs/src/fmi2_lowlevel_modeldescription_functions.md b/docs/src/fmi2_lowlevel_modeldescription_functions.md index 4a781252..07c5a65d 100644 --- a/docs/src/fmi2_lowlevel_modeldescription_functions.md +++ b/docs/src/fmi2_lowlevel_modeldescription_functions.md @@ -5,95 +5,63 @@ The FMI model description provides all human readable information on the model. ## Loading/Parsing ```@docs -fmi2LoadModelDescription ``` +fmi2LoadModelDescription ## general information about the FMU ```@docs -fmi2GetModelName -fmi2GetGUID -fmi2IsCoSimulation -fmi2IsModelExchange +``` fmi2GetGenerationTool fmi2GetGenerationDateAndTime -``` ## technical information about the FMU ```@docs -fmi2GetModelIdentifier -fmi2GetVariableNamingConvention fmi2GetVersion fmi2GetTypesPlatform -fmi2GetNumberOfEventIndicators -``` - -## default experiment settings - -```@docs -fmi2GetDefaultStartTime -fmi2GetDefaultStopTime -fmi2GetDefaultTolerance -fmi2GetDefaultStepSize ``` ## FMU capabilities ```@docs +canGetSetFMUState +isModelStructureAvailable +isModelStructureDerivativesAvailable +``` fmi2DependenciesSupported fmi2DerivativeDependenciesSupported -fmi2CanGetSetState fmi2CanSerializeFMUstate fmi2ProvidesDirectionalDerivative -``` ## value references ```@docs +getModelVariableIndices +``` fmi2GetValueReferencesAndNames fmi2GetNames -fmi2GetModelVariableIndices -fmi2DataTypeForValueReference -``` ## In-/Outputs ```@docs -fmi2GetInputValueReferencesAndNames -fmi2GetInputNames -fmi2GetOutputValueReferencesAndNames -fmi2GetOutputNames ``` +fmi2GetOutputValueReferencesAndNames -## Parameters - -```@docs -fmi2GetParameterValueReferencesAndNames -fmi2GetParameterNames -``` ## States ```@docs -fmi2GetNumberOfStates -fmi2GetStateValueReferencesAndNames -fmi2GetStateNames ``` ## Derivatives ```@docs -fmi2GetDerivateValueReferencesAndNames -fmi2GetDerivativeNames ``` ## Variables ```@docs -fmi2GetNamesAndDescriptions -fmi2GetNamesAndUnits -fmi2GetNamesAndInitials -fmi2GetInputNamesAndStarts ``` + diff --git a/docs/src/fmi3_lowlevel_CS_functions.md b/docs/src/fmi3_lowlevel_CS_functions.md index 731073f3..a47839cc 100644 --- a/docs/src/fmi3_lowlevel_CS_functions.md +++ b/docs/src/fmi3_lowlevel_CS_functions.md @@ -11,8 +11,8 @@ derivatives of the inputs with respect to time can be provided. Also, higher der higher order interpolation. ```@docs -fmi3CallbackIntermediateUpdate ``` +fmi3CallbackIntermediateUpdate ## Computation The computation of time steps is controlled by the following function. diff --git a/docs/src/fmi3_lowlevel_ME_functions.md b/docs/src/fmi3_lowlevel_ME_functions.md index f28ef4a2..99c2376d 100644 --- a/docs/src/fmi3_lowlevel_ME_functions.md +++ b/docs/src/fmi3_lowlevel_ME_functions.md @@ -9,6 +9,8 @@ Depending on the situation, different variables need to be computed. In order to ```@docs fmi3SetTime fmi3SetContinuousStates +fmi3GetEventIndicators +fmi3GetEventIndicators! ``` ## Evaluation of Model Equations @@ -16,11 +18,12 @@ fmi3SetContinuousStates ```@docs fmi3EnterEventMode fmi3EnterContinuousTimeMode -fmi3CompletedIntegratorStep fmi3CompletedIntegratorStep! -fmi3GetEventIndicators! +fmi3GetContinuousStates fmi3GetContinuousStates! +fmi3GetNominalsOfContinuousStates fmi3GetNominalsOfContinuousStates! fmi3GetNumberOfContinuousStates fmi3GetNumberOfContinuousStates! ``` +fmi3CompletedIntegratorStep diff --git a/docs/src/fmi3_lowlevel_library_constants.md b/docs/src/fmi3_lowlevel_library_constants.md index cb1ea073..24d6cc01 100644 --- a/docs/src/fmi3_lowlevel_library_constants.md +++ b/docs/src/fmi3_lowlevel_library_constants.md @@ -1,3 +1,47 @@ +# FMI3 Types in FMI Import/Core .jl + +```@docs +FMU3 +FMU3Instance +FMU3InstanceEnvironment +FMI3Struct +fmi3Instance +fmi3InstanceEnvironment +fmi3InstanceState +fmi3FMUState +fmi3Initial +fmi3ValueReference +fmi3Variable +fmi3VariableDependency +fmi3Binary +fmi3SimpleType +fmi3Type +fmi3Unit +fmi3Boolean +fmi3Byte +fmi3Char +fmi3Float32 +fmi3Float64 +fmi3Int8 +fmi3Int16 +fmi3Int32 +fmi3Int64 +fmi3UInt8 +fmi3UInt16 +fmi3UInt32 +fmi3UInt64 +fmi3String +fmi3Clock +fmi3IntervalQualifier +fmi3Variability +fmi3DependencyKind +fmi3Status +fmi3Annotation +fmi3ModelDescription +fmi3VariableNamingConvention +fmi3Causality +``` + # FMI3 Constants in FMI Import/Core .jl ```@docs @@ -8,6 +52,24 @@ fmi3StatusWarning fmi3StatusDiscard fmi3StatusError fmi3StatusFatal +fmi3InstanceStateInstantiated +fmi3InstanceStateInitializationMode +fmi3InstanceStateEventMode +fmi3InstanceStateStepMode +fmi3InstanceStateClockActivationMode +fmi3InstanceStateContinuousTimeMode +fmi3InstanceStateConfigurationMode +fmi3InstanceStateReconfigurationMode +fmi3InstanceStateTerminated +fmi3InstanceStateError +fmi3InstanceStateFatal fmi3VariableNamingConventionFlat fmi3VariableNamingConventionStructured -``` +fmi3CausalityParameter +fmi3CausalityCalculatedParameter +fmi3CausalityInput +fmi3CausalityOutput +fmi3CausalityLocal +fmi3CausalityIndependent +fmi3CausalityStructuralParameter +``` \ No newline at end of file diff --git a/docs/src/fmi3_lowlevel_library_functions.md b/docs/src/fmi3_lowlevel_library_functions.md index f3d166a7..1bb0705b 100644 --- a/docs/src/fmi3_lowlevel_library_functions.md +++ b/docs/src/fmi3_lowlevel_library_functions.md @@ -5,11 +5,11 @@ platform dependent header file, several access functions, as well as the schema ## Opening and closing FMUs ```@docs +``` fmi3Unzip fmi3Load fmi3Reload fmi3Unload -``` ## Creation, Destruction and Logging of FMU Instances @@ -20,6 +20,7 @@ fmi3InstantiateModelExchange fmi3InstantiateModelExchange! fmi3InstantiateScheduledExecution fmi3InstantiateScheduledExecution! +fmi3FreeInstance fmi3FreeInstance! fmi3SetDebugLogging ``` @@ -45,8 +46,6 @@ have identical values but other parts of the variable definition might be differ attributes). ```@docs -fmi3Get -fmi3Get! fmi3GetFloat32 fmi3GetFloat32! fmi3GetFloat64 @@ -73,7 +72,6 @@ fmi3GetString fmi3GetString! fmi3GetBinary fmi3GetBinary! -fmi3Set fmi3SetFloat32 fmi3SetFloat64 fmi3SetInt8 @@ -88,6 +86,9 @@ fmi3SetBoolean fmi3SetString fmi3SetBinary ``` +fmi3Get +fmi3Get! +fmi3Set ## Getting and Setting the Complete FMU State The FMU has an internal state consisting of all values that are needed to continue a simulation. This internal state consists especially of the values of the continuous-time states, iteration variables, parameter values, input values, delay buffers, file identifiers, and FMU internal status information. With the functions of this section, the internal FMU state can be copied and the pointer to this copy is returned to the environment. The FMU state copy can be set as actual FMU state, in order to continue the simulation from it. @@ -96,7 +97,7 @@ The FMU has an internal state consisting of all values that are needed to contin fmi3GetFMUState fmi3GetFMUState! fmi3SetFMUState -fmi3FreeFMUState! +fmi3FreeFMUState fmi3SerializeFMUState fmi3SerializeFMUState! fmi3SerializedFMUStateSize @@ -116,18 +117,19 @@ directional derivatives. This function can be used to construct the desired part ```@docs fmi3GetDirectionalDerivative fmi3GetDirectionalDerivative! -fmi3SampleDirectionalDerivative -fmi3SampleDirectionalDerivative! fmi3GetContinuousStateDerivatives fmi3GetContinuousStateDerivatives! +fmi3GetAdjointDerivative fmi3GetAdjointDerivative! fmi3GetOutputDerivatives fmi3GetOutputDerivatives! +``` +fmi3SampleDirectionalDerivative +fmi3SampleDirectionalDerivative! fmi3GetJacobian fmi3GetJacobian! fmi3GetFullJacobian fmi3GetFullJacobian! -``` ## TODO: Clockstuff @@ -142,38 +144,27 @@ fmi3GetClock fmi3GetClock! fmi3SetClock fmi3ActivateModelPartition -fmi3CallbackClockUpdate ``` +fmi3CallbackClockUpdate ## Conversion functions ```@docs -fmi3StringToValueReference -fmi3ValueReferenceToString +stringToType +typeToString +stringToVariableNamingConvention +variableNamingConventionToString +intervalQualifierToString +``` fmi3StringToCausality -fmi3CausalityToString -fmi3StringToVariability -fmi3VariabilityToString -fmi3StringToStatus fmi3StatusToString -fmi3StringToDependencyKind -fmi3DependencyKindToString fmi3StringToInitial -fmi3InitialToString -fmi3IntervalQualifierToString -fmi3StringToIntervalQualifier -fmi3StringToType -fmi3TypeToString -fmi3VariableNamingConventionToString -fmi3StringToVariableNamingConvention -``` ## External/Additional functions ```@docs -fmi3ModelVariablesForValueReference -fmi3GetStartValue - +fmi3GetNumberOfVariableDependencies fmi3GetNumberOfVariableDependencies! +fmi3GetVariableDependencies fmi3GetVariableDependencies! ``` \ No newline at end of file diff --git a/docs/src/fmi3_lowlevel_library_types.md b/docs/src/fmi3_lowlevel_library_types.md deleted file mode 100644 index 6c74452e..00000000 --- a/docs/src/fmi3_lowlevel_library_types.md +++ /dev/null @@ -1,37 +0,0 @@ -# FMI3 Types in FMI Import/Core .jl - -```@docs -FMU3 -FMU3Instance -FMU3InstanceEnvironment -fmi3Struct -fmi3StructMD -fmi3Initial -FMU3Solution -fmi3Variable -fmi3VariableDependency -fmi3SimpleType -fmi3Type -fmi3Unit -fmi3Float32 -fmi3Float64 -fmi3Int8 -fmi3Int16 -fmi3Int32 -fmi3Int64 -fmi3UInt8 -fmi3UInt16 -fmi3UInt32 -fmi3UInt64 -FMIImport.fmi3ValueReferenceFormat -fmi3IntervalQualifier -fmi3Variability -fmi3DependencyKind -FMU3Event -FMU3ExecutionConfiguration -fmi3Status -fmi3Annotation -fmi3ModelDescription -fmi3VariableNamingConvention -fmi3Causality -``` \ No newline at end of file diff --git a/docs/src/fmi3_lowlevel_modeldescription_functions.md b/docs/src/fmi3_lowlevel_modeldescription_functions.md index 164b3965..5cddbde8 100644 --- a/docs/src/fmi3_lowlevel_modeldescription_functions.md +++ b/docs/src/fmi3_lowlevel_modeldescription_functions.md @@ -5,46 +5,28 @@ The FMI model description provides all human readable information on the model. ## Loading/Parsing ```@docs -fmi3LoadModelDescription ``` +fmi3LoadModelDescription ## general information about the FMU ```@docs -fmi3GetModelName -fmi3GetInstantiationToken -fmi3IsCoSimulation -fmi3IsModelExchange -fmi3IsScheduledExecution +``` fmi3GetGenerationTool fmi3GetGenerationDateAndTime -``` ## technical information about the FMU ```@docs -fmi3GetModelIdentifier -fmi3GetVariableNamingConvention fmi3GetVersion fmi3GetNumberOfEventIndicators fmi3GetNumberOfEventIndicators! ``` -## default experiment settings - -```@docs -fmi3GetDefaultStartTime -fmi3GetDefaultStopTime -fmi3GetDefaultTolerance -fmi3GetDefaultStepSize -``` - ## FMU capabilities ```@docs +``` fmi3CanGetSetState -fmi3CanSerializeFMUState -fmi3ProvidesDirectionalDerivatives -fmi3ProvidesAdjointDerivatives -``` \ No newline at end of file +fmi3CanSerializeFMUState \ No newline at end of file diff --git a/docs/src/fmi_lowlevel_library_constants.md b/docs/src/fmi_lowlevel_library_constants.md index 03b7456f..cc8c256e 100644 --- a/docs/src/fmi_lowlevel_library_constants.md +++ b/docs/src/fmi_lowlevel_library_constants.md @@ -1,3 +1,16 @@ +# Types in FMI Import/Core .jl + +```@docs +FMU +FMUInstance +FMUSolution +FMUEvent +FMUSnapshot +FMUExecutionConfiguration +FMULogLevel +FMUInputFunction +``` + # Constants in FMI Import/Core .jl ```@docs diff --git a/docs/src/fmi_lowlevel_library_functions.md b/docs/src/fmi_lowlevel_library_functions.md index a56404e7..067fc4e7 100644 --- a/docs/src/fmi_lowlevel_library_functions.md +++ b/docs/src/fmi_lowlevel_library_functions.md @@ -4,6 +4,48 @@ logInfo logWarning logError +``` loadBinary eval! -``` \ No newline at end of file + +## Conversion functions + +```@docs +stringToStatus +statusToString +stringToDependencyKind +dependencyKindToString +valueReferenceToString +stringToInitial +initialToString +stringToIntervalQualifier +stringToDataType +stringToCausality +causalityToString +stringToVariability +variabilityToString +``` + +fmi2StringToInitial + +## External/Additional functions + +```@docs +getInitial +getStartValue +hasCurrentInstance +getCurrentInstance +modelVariablesForValueReference +setValue +getValue +getValue! +getUnit +``` +fmi2GetSolutionDerivative +fmi2GetSolutionState +fmi2GetSolutionValue +fmi2GetSolutionTime +fmi2GetJacobian +fmi2GetJacobian! +fmi2GetFullJacobian +fmi2GetFullJacobian! diff --git a/docs/src/fmi_lowlevel_library_types.md b/docs/src/fmi_lowlevel_library_types.md deleted file mode 100644 index 12256adb..00000000 --- a/docs/src/fmi_lowlevel_library_types.md +++ /dev/null @@ -1,9 +0,0 @@ -# Types in FMI Import/Core .jl - -```@docs -FMU -FMUSolution -FMUEvent -FMUExecutionConfiguration -FMULogLevel -``` \ No newline at end of file diff --git a/docs/src/fmi_lowlevel_modeldescription_functions.md b/docs/src/fmi_lowlevel_modeldescription_functions.md new file mode 100644 index 00000000..006ff460 --- /dev/null +++ b/docs/src/fmi_lowlevel_modeldescription_functions.md @@ -0,0 +1,98 @@ +# Working with the FMI model description + +The FMI model description provides all human readable information on the model. The following functions can be used to obtain all information provided by the model description, which in turn can be extracted from the fmu. + +## Loading/Parsing + +```@docs +``` +fmi2LoadModelDescription + +## general information about the FMU + +```@docs +getGUID +getInstantiationToken +getGenerationDateAndTime +getGenerationTool +``` + +## technical information about the FMU + +```@docs +getNumberOfEventIndicators +getModelIdentifier +getVariableNamingConvention +``` +fmi2GetVersion +fmi2GetTypesPlatform + +## default experiment settings + +```@docs +getDefaultStartTime +getDefaultStepSize +getDefaultStopTime +getDefaultTolerance +``` + +## FMU capabilities + +```@docs +canSerializeFMUState +providesDirectionalDerivatives +providesAdjointDerivatives +``` +canGetSetFMUState +fmi2DependenciesSupported +fmi2DerivativeDependenciesSupported +fmi2ProvidesDirectionalDerivative + +## value references + +```@docs +getValueReferencesAndNames +getNames +dataTypeForValueReference +prepareValueReference +prepareValue +``` + +## In-/Outputs + +```@docs +getInputNames +getInputValueReferencesAndNames +getInputNamesAndStarts +getOutputNames +getOutputValueReferencesAndNames +``` + +## Parameters + +```@docs +getParameterValueReferencesAndNames +getParameterNames +``` + +## States + +```@docs +getStateNames +getStateValueReferencesAndNames +``` + +## Derivatives + +```@docs +getDerivateValueReferencesAndNames +getDerivativeNames +``` + +## Variables + +```@docs +getNamesAndInitials +getNamesAndDescriptions +getNamesAndUnits +``` diff --git a/docs/src/library.md b/docs/src/library.md index f3af5c7d..5b8126c0 100644 --- a/docs/src/library.md +++ b/docs/src/library.md @@ -5,81 +5,78 @@ Many of the functions in this library are based on already defined functions of # Simulate FMUs ```@docs -fmiLoad -fmiSimulate -fmiSimulateCS -fmiSimulateME -fmiUnload -fmiReload +loadFMU +simulate +simulateCS +simulateSE +simulateME +unloadFMU +reload ``` + # Handling Value References ```@docs -fmiStringToValueReference -fmiGetStartValue +stringToValueReference ``` # External/additional functions ```@docs -fmiInfo +info +getModelName +getNumberOfStates +isModelExchange +isScheduledExecution +isCoSimulation +getState +getTime +getStateDerivative +``` fmiSet fmiGet fmiGet! -fmiGetNumberOfStates fmiCanGetSetState -fmiGetState fmiSetState fmiFreeState! fmiGetDependencies fmiProvidesDirectionalDerivative -fmiGetModelName -fmiGetGUID -fmiIsCoSimulation -fmiIsModelExchange -fmiIsScheduledExecution -``` # Visualize simulation results ```@docs +``` fmiPlot fmiPlot! Plots.plot -``` # Save/load simulation results ```@docs +``` fmiSaveSolution fmiSaveSolutionJLD2 fmiSaveSolutionMAT fmiSaveSolutionCSV fmiLoadSolution fmiLoadSolutionJLD2 -``` # FMI2 specific ```@docs +``` fmi2Info fmi2Simulate -fmi2SimulateME -fmi2SimulateCS fmi2VariableDependsOnVariable fmi2GetDependencies fmi2PrintDependencies -``` # FMI3 specific ```@docs +``` fmi3Info fmi3Simulate -fmi3SimulateME -fmi3SimulateSE -fmi3SimulateCS fmi3VariableDependsOnVariable fmi3GetDependencies -fmi3PrintDependencies -``` \ No newline at end of file +fmi3PrintDependencies \ No newline at end of file diff --git a/examples/src/simulate.ipynb b/examples/src/simulate.ipynb index 41b8a17b..1b99dcb6 100644 --- a/examples/src/simulate.ipynb +++ b/examples/src/simulate.ipynb @@ -36,7 +36,7 @@ "metadata": {}, "source": [ "## Motivation\n", - "This Julia Package *FMI.jl* is motivated by the use of simulation models in Julia. Here the FMI specification is implemented. FMI (*Functional Mock-up Interface*) is a free standard ([fmi-standard.org](http://fmi-standard.org/)) that defines a container and an interface to exchange dynamic models using a combination of XML files, binaries and C code zipped into a single file. The user can thus use simulation models in the form of an FMU (*Functional Mock-up Units*). Besides loading the FMU, the user can also set values for parameters and states and simulate the FMU both as co-simulation and model exchange simulation.\n", + "This Julia Package *FMI.jl* is motivated by the use of simulation models in Julia. Here the FMI specification is implemented. FMI (*Functional Mock-up Interface*) is a free standard ([fmi-standard.org](https://fmi-standard.org/)) that defines a container and an interface to exchange dynamic models using a combination of XML files, binaries and C code zipped into a single file. The user can thus use simulation models in the form of an FMU (*Functional Mock-up Units*). Besides loading the FMU, the user can also set values for parameters and states and simulate the FMU both as co-simulation and model exchange simulation.\n", "\n", "## Introduction to the example\n", "In this example we want to show how fast and easy the simulation for an FMU is. For this purpose, the FMU is simulated in co-simulation mode and in model-exchange mode. After the FMU has been simulated, the simulation results are displayed in a graph. The graphs of the different modes are compared with each other. The used model is a one-dimensional spring pendulum with friction. The object-orientated structure of the *SpringFrictionPendulum1D* can be seen in the following graphic.\n", diff --git a/src/FMI.jl b/src/FMI.jl index 8d012e58..a93687e5 100644 --- a/src/FMI.jl +++ b/src/FMI.jl @@ -7,1232 +7,11 @@ module FMI @debug "Debugging messages enabled for FMI.jl ..." -using Requires - -using FMIImport - -import FMIImport.FMICore: unsense, getCurrentComponent - -# TODO recheck export import list -# fmi2 imports -import FMIImport: fmi2CallbackLogger, fmi2CallbackAllocateMemory, fmi2CallbackFreeMemory, fmi2CallbackStepFinished -import FMIImport: fmi2ComponentState, fmi2ComponentStateInstantiated, fmi2ComponentStateInitializationMode, fmi2ComponentStateEventMode, fmi2ComponentStateContinuousTimeMode, fmi2ComponentStateTerminated, fmi2ComponentStateError, fmi2ComponentStateFatal -import FMIImport: fmi2Instantiate, fmi2FreeInstance!, fmi2GetTypesPlatform, fmi2GetVersion -import FMIImport: fmi2SetDebugLogging, fmi2SetupExperiment, fmi2EnterInitializationMode, fmi2ExitInitializationMode, fmi2Terminate, fmi2Reset -import FMIImport: fmi2GetReal!, fmi2SetReal, fmi2GetInteger!, fmi2SetInteger, fmi2GetBoolean!, fmi2SetBoolean, fmi2GetString!, fmi2SetString -import FMIImport: fmi2GetFMUstate!, fmi2SetFMUstate, fmi2FreeFMUstate!, fmi2SerializedFMUstateSize!, fmi2SerializeFMUstate!, fmi2DeSerializeFMUstate! -import FMIImport: fmi2GetDirectionalDerivative!, fmi2SetRealInputDerivatives, fmi2GetRealOutputDerivatives -import FMIImport: fmi2DoStep, fmi2CancelStep, fmi2GetStatus!, fmi2GetRealStatus!, fmi2GetIntegerStatus!, fmi2GetBooleanStatus!, fmi2GetStringStatus! -import FMIImport: fmi2SetTime, fmi2SetContinuousStates, fmi2EnterEventMode, fmi2NewDiscreteStates, fmi2EnterContinuousTimeMode, fmi2CompletedIntegratorStep! -import FMIImport: fmi2GetDerivatives, fmi2GetEventIndicators, fmi2GetContinuousStates, fmi2GetNominalsOfContinuousStates -import FMIImport: fmi2StringToValueReference, fmi2ValueReferenceToString, fmi2ModelVariablesForValueReference -import FMIImport: fmi2GetReal, fmi2GetInteger, fmi2GetString, fmi2GetBoolean -import FMIImport: fmi2GetFMUstate, fmi2SerializedFMUstateSize, fmi2SerializeFMUstate, fmi2DeSerializeFMUstate -import FMIImport: fmi2GetDirectionalDerivative -import FMIImport: fmi2GetStartValue, fmi2SampleJacobian, fmi2CompletedIntegratorStep -import FMIImport: fmi2Unzip, fmi2Load, loadBinary, fmi2Reload, fmi2Unload, fmi2Instantiate! -import FMIImport: fmi2SampleJacobian! -import FMIImport: fmi2GetJacobian, fmi2GetJacobian!, fmi2GetFullJacobian, fmi2GetFullJacobian! -import FMIImport: fmi2LoadModelDescription -import FMIImport: fmi2GetDefaultStartTime, fmi2GetDefaultStopTime, fmi2GetDefaultTolerance, fmi2GetDefaultStepSize -import FMIImport: fmi2GetModelName, fmi2GetGUID, fmi2GetGenerationTool, fmi2GetGenerationDateAndTime, fmi2GetVariableNamingConvention, fmi2GetNumberOfEventIndicators, fmi2GetNumberOfStates, fmi2IsCoSimulation, fmi2IsModelExchange -import FMIImport: fmi2DependenciesSupported, fmi2GetModelIdentifier, fmi2CanGetSetState, fmi2CanSerializeFMUstate, fmi2ProvidesDirectionalDerivative -import FMIImport: fmi2Get, fmi2Get!, fmi2Set -import FMIImport: fmi2GetSolutionTime, fmi2GetSolutionState, fmi2GetSolutionValue -export fmi2GetSolutionTime, fmi2GetSolutionState, fmi2GetSolutionValue - -# fmi3 imports -import FMIImport: fmi3CallbackLogger, fmi3CallbackIntermediateUpdate, fmi3CallbackClockUpdate -import FMIImport: fmi3InstanceState, fmi3InstanceStateInstantiated, fmi3InstanceStateInitializationMode, fmi3InstanceStateEventMode, fmi3InstanceStateContinuousTimeMode, fmi3InstanceStateTerminated, fmi3InstanceStateError, fmi3InstanceStateFatal -import FMIImport: fmi3InstantiateModelExchange!, fmi3InstantiateCoSimulation!, fmi3InstantiateScheduledExecution!, fmi3FreeInstance!, fmi3GetVersion -import FMIImport: fmi3SetDebugLogging, fmi3EnterInitializationMode, fmi3ExitInitializationMode, fmi3Terminate, fmi3Reset -import FMIImport: fmi3GetFloat32!, fmi3SetFloat32, fmi3GetFloat64!, fmi3SetFloat64 -import FMIImport: fmi3GetInt8!, fmi3SetInt8, fmi3GetUInt8!, fmi3SetUInt8, fmi3GetInt16!, fmi3SetInt16, fmi3GetUInt16!, fmi3SetUInt16, fmi3GetInt32!, fmi3SetInt32, fmi3GetUInt32!, fmi3SetUInt32, fmi3GetInt64!, fmi3SetInt64, fmi3GetUInt64!, fmi3SetUInt64 -import FMIImport: fmi3GetBoolean!, fmi3SetBoolean, fmi3GetString!, fmi3SetString, fmi3GetBinary!, fmi3SetBinary, fmi3GetClock!, fmi3SetClock -import FMIImport: fmi3GetFMUState!, fmi3SetFMUState, fmi3FreeFMUState!, fmi3SerializedFMUStateSize!, fmi3SerializeFMUState!, fmi3DeSerializeFMUState! -import FMIImport: fmi3SetIntervalDecimal, fmi3SetIntervalFraction, fmi3GetIntervalDecimal!, fmi3GetIntervalFraction!, fmi3GetShiftDecimal!, fmi3GetShiftFraction! -import FMIImport: fmi3ActivateModelPartition -import FMIImport: fmi3GetNumberOfVariableDependencies!, fmi3GetVariableDependencies! -import FMIImport: fmi3GetDirectionalDerivative!, fmi3GetAdjointDerivative!, fmi3GetOutputDerivatives! -import FMIImport: fmi3DoStep! - -import FMIImport: fmi3EnterConfigurationMode, fmi3ExitConfigurationMode, fmi3GetNumberOfContinuousStates!, fmi3GetNumberOfEventIndicators!, fmi3GetContinuousStates!, fmi3GetNominalsOfContinuousStates! -import FMIImport: fmi3EvaluateDiscreteStates, fmi3EnterStepMode -import FMIImport: fmi3SetTime, fmi3SetContinuousStates, fmi3EnterEventMode, fmi3UpdateDiscreteStates, fmi3EnterContinuousTimeMode, fmi3CompletedIntegratorStep! -import FMIImport: fmi3GetContinuousStateDerivatives, fmi3GetContinuousStateDerivatives!, fmi3GetEventIndicators, fmi3GetContinuousStates, fmi3GetNominalsOfContinuousStates -import FMIImport: fmi3StringToValueReference, fmi3ValueReferenceToString, fmi3ModelVariablesForValueReference -import FMIImport: fmi3GetFloat32, fmi3GetFloat64, fmi3GetInt8, fmi3GetUInt8, fmi3GetInt16, fmi3GetUInt16, fmi3GetInt32, fmi3GetUInt32, fmi3GetInt64, fmi3GetUInt64, fmi3GetBoolean, fmi3GetBinary, fmi3GetClock, fmi3GetString -import FMIImport: fmi3SetFloat32, fmi3SetFloat64, fmi3SetInt8, fmi3SetUInt8, fmi3SetInt16, fmi3SetUInt16, fmi3SetInt32, fmi3SetUInt32, fmi3SetInt64, fmi3SetUInt64, fmi3SetBoolean, fmi3SetBinary, fmi3SetClock, fmi3SetString -import FMIImport: fmi3GetFMUState, fmi3SerializedFMUStateSize, fmi3SerializeFMUState, fmi3DeSerializeFMUState -import FMIImport: fmi3GetDirectionalDerivative, fmi3GetAdjointDerivative -import FMIImport: fmi3GetStartValue, fmi3SampleDirectionalDerivative, fmi3CompletedIntegratorStep -import FMIImport: fmi3Unzip, fmi3Load, loadBinary, fmi3Reload, fmi3Unload -import FMIImport: fmi3SampleDirectionalDerivative! -import FMIImport: fmi3GetJacobian, fmi3GetJacobian!, fmi3GetFullJacobian, fmi3GetFullJacobian! -import FMIImport: fmi3LoadModelDescription -import FMIImport: fmi3GetDefaultStartTime, fmi3GetDefaultStopTime, fmi3GetDefaultTolerance, fmi3GetDefaultStepSize -import FMIImport: fmi3GetModelName, fmi3GetInstantiationToken, fmi3GetGenerationTool, fmi3GetGenerationDateAndTime, fmi3GetVariableNamingConvention, fmi3GetNumberOfEventIndicators, fmi3GetNumberOfContinuousStates, fmi3IsCoSimulation, fmi3IsModelExchange, fmi3IsScheduledExecution -# import FMIImport: fmi3DependenciesSupported -import FMIImport:fmi3GetModelIdentifier, fmi3CanGetSetState, fmi3CanSerializeFMUState, fmi3ProvidesDirectionalDerivatives, fmi3ProvidesAdjointDerivatives -import FMIImport: fmi3Get, fmi3Get!, fmi3Set -# import FMIImport: fmi3GetSolutionTime, fmi3GetSolutionState, fmi3GetSolutionValue -# export fmi3GetSolutionTime, fmi3GetSolutionState, fmi3GetSolutionValue -export fmi3InstantiateCoSimulation!, fmi3InstantiateModelExchange!, fmi3InstantiateScheduledExecution! -export fmi3EnterInitializationMode, fmi3ExitInitializationMode -export fmi3GetFloat32, fmi3GetFloat64, fmi3GetInt8, fmi3GetUInt8, fmi3GetInt16, fmi3GetUInt16, fmi3GetInt32, fmi3GetUInt32, fmi3GetInt64, fmi3GetUInt64, fmi3GetBoolean, fmi3GetBinary, fmi3GetClock, fmi3GetString -export fmi3SetFloat64 -export fmi3UpdateDiscreteStates, fmi3GetContinuousStateDerivatives! - -import FMIImport: fmi2TypeModelExchange, fmi2TypeCoSimulation, fmi2Type -export fmi2TypeModelExchange, fmi2TypeCoSimulation, fmi2Type - -export fmiCanGetSetState - -import FMIImport: fmi3TypeModelExchange, fmi3TypeCoSimulation, fmi3TypeScheduledExecution, fmi3Type -export fmi2TypeModelExchange, fmi2TypeCoSimulation, fmi3TypeScheduledExecution, fmi2Type - -using FMIExport -using FMIExport: fmi2Create, fmi2CreateSimple - -using FMIImport.FMICore: fmi2ValueReference, fmi3ValueReference -using FMIImport: fmi2ValueReferenceFormat, fmi3ValueReferenceFormat, fmi2StructMD, fmi3StructMD, fmi2Struct, fmi3Struct - -using FMIImport.FMICore: FMU, FMU2, FMU3, FMU2Component, FMU3Instance, FMUSolution -export FMU, FMU2, FMU3, FMU2Component, FMU3Instance - -using FMIImport.FMICore: FMU2ExecutionConfiguration, FMU2_EXECUTION_CONFIGURATION_RESET, FMU2_EXECUTION_CONFIGURATION_NO_RESET, FMU2_EXECUTION_CONFIGURATION_NO_FREEING -export FMU2ExecutionConfiguration, FMU2_EXECUTION_CONFIGURATION_RESET, FMU2_EXECUTION_CONFIGURATION_NO_RESET, FMU2_EXECUTION_CONFIGURATION_NO_FREEING - -using FMIImport.FMICore: FMU3ExecutionConfiguration, FMU3_EXECUTION_CONFIGURATION_RESET, FMU3_EXECUTION_CONFIGURATION_NO_RESET, FMU3_EXECUTION_CONFIGURATION_NO_FREEING -export FMU3ExecutionConfiguration, FMU3_EXECUTION_CONFIGURATION_RESET, FMU3_EXECUTION_CONFIGURATION_NO_RESET, FMU3_EXECUTION_CONFIGURATION_NO_FREEING - -using FMIImport: prepareValue, prepareValueReference - -export fmi2Real, fmi2Integer, fmi2String, fmi2Boolean -export fmi2Info, fmi3Info -export fmi2VariableDependsOnVariable, fmi2GetDependencies, fmi2PrintDependencies, fmi3VariableDependsOnVariable, fmi3GetDependencies, fmi3PrintDependencies - -include("check.jl") - -include("FMI2/additional.jl") -include("FMI3/additional.jl") -include("assertions.jl") - -include("FMI2/comp_wraps.jl") -include("FMI3/comp_wraps.jl") - -include("FMI2/sim.jl") -include("FMI3/sim.jl") +using FMIImport.FMIBase.Reexport +@reexport using FMIImport +@reexport using FMIExport +include("sim.jl") include("deprecated.jl") -# from FMI2_plot.jl -# function fmiPlot(solution::FMUSolution; kwargs...) -# @assert false "fmiPlot(...) needs `Plots` package. Please install `Plots` and do `using Plots` or `import Plots`." -# end -# function fmiPlot!(fig, solution::FMUSolution; kwargs...) -# @assert false "fmiPlot!(...) needs `Plots` package. Please install `Plots` and do `using Plots` or `import Plots`." -# end -# export fmiPlot, fmiPlot! - -# from FMI2_JLD2.jl -# function fmiSaveSolutionJLD2(solution::FMUSolution, filepath::AbstractString; keyword="solution") -# @assert false "fmiSave(...) needs `JLD2` package. Please install `JLD2` and do `using JLD2` or `import JLD2`." -# end -# function fmiLoadSolutionJLD2(path::AbstractString; keyword="solution") -# @assert false "fmiLoad(...) needs `JLD2` package. Please install `JLD2` and do `using JLD2` or `import JLD2`." -# end -# export fmiSaveSolutionJLD2, fmiLoadSolutionJLD2 - -# from CSV.jl -# function fmiSaveSolutionCSV(solution::FMUSolution, filepath::AbstractString) -# @assert false "fmiSave(...) needs `CSV` and `DataFrames` package. Please install `CSV` and `DataFrames` and do `using CSV, DataFrames` or `import CSV, DataFrames`." -# end -# export fmiSaveSolutionCSV - -# from MAT.jl -# function fmiSaveSolutionMAT(solution::FMUSolution, filepath::AbstractString) -# @assert false "fmiSave(...) needs `MAT` package. Please install `MAT` and do `using MAT` or `import MAT`." -# end -# export fmiSaveSolutionMAT - -# from FMI3_plot.jl -# function fmiPlot(solution::FMU3Solution; kwargs...) -# @warn "fmiPlot(...) needs `Plots` package. Please install `Plots` and do `using Plots` or `import Plots`." -# end -# function fmiPlot!(fig, solution::FMU3Solution; kwargs...) -# @warn "fmiPlot!(...) needs `Plots` package. Please install `Plots` and do `using Plots` or `import Plots`." -# end -# export fmiPlot, fmiPlot! - -# from FMI3_JLD2.jl -# function fmiSaveSolution(solution::FMU3Solution, filepath::AbstractString; keyword="solution") -# @warn "fmiSave(...) needs `JLD2` package. Please install `JLD2` and do `using JLD2` or `import JLD2`." -# end -# function fmiLoadSolution(path::AbstractString; keyword="solution") -# @warn "fmiLoad(...) needs `JLD2` package. Please install `JLD2` and do `using JLD2` or `import JLD2`." -# end - -# Requires init -function __init__() - @require Plots="91a5bcdd-55d7-5caf-9e0b-520d859cae80" begin - import .Plots - include("extensions/Plots.jl") - end - @require JLD2="033835bb-8acc-5ee8-8aae-3f567f8a3819" begin - import .JLD2 - include("extensions/JLD2.jl") - end - @require DataFrames="a93c6f00-e57d-5684-b7b6-d8193f3e46c0" begin - import .DataFrames - @require CSV="336ed68f-0bac-5ca0-87d4-7b16caf5d00b" begin - import .CSV - include("extensions/CSV.jl") - end - end - @require MAT="23992714-dd62-5051-b70f-ba57cb901cac" begin - import .MAT - include("extensions/MAT.jl") - end -end - -### EXPORTING LISTS START ### - -# FMI.jl -export fmiLoad, fmiReload, fmiSimulate, fmiSimulateCS, fmiSimulateME, fmiUnload -export fmiInfo -export fmiGetModelName, fmiGetGUID, fmiGetGenerationTool, fmiGetGenerationDateAndTime - -export fmiProvidesDirectionalDerivative -export fmiIsCoSimulation, fmiIsModelExchange, fmiIsScheduledExecution -export fmiGetDependencies -export fmiGetStartValue, fmiStringToValueReference -export fmiGet, fmiGet!, fmiSet -export fmiGetSolutionTime, fmiGetSolutionState, fmiGetSolutionDerivative, fmiGetSolutionValue -export fmiGetNumberOfStates - -export fmiGetState, fmiSetState, fmiFreeState! - -### EXPORTING LISTS END ### - -""" - (str::Union{fmi2Struct, fmi3Struct})(; t::Tuple{Float64, Float64}, kwargs...) - -Wrapper for dispatch to [`fmiSimulate`](@ref). -""" -function (str::Union{fmi2Struct, fmi3Struct})(; t::Tuple{Float64, Float64}, kwargs...) - fmiSimulate(str, t; kwargs...) -end - -""" - fmiGetState(str::fmi2Struct) - -Wrapper for [`fmi2GetFMUstate`](@ref). - -See also [`fmiSetState`](@ref), [`fmiFreeState!`](@ref). -""" -function fmiGetState(str::fmi2Struct) - fmi2GetFMUstate(str) -end - -""" - fmiGetState(str::fmi3Struct) - -Wrapper for [`fmi3GetFMUState`](@ref). - -See also [`fmiSetState`](@ref), [`fmiFreeState!`](@ref). -""" -function fmiGetState(str::fmi3Struct) - fmi3GetFMUState(str) -end - -""" - fmiFreeState!(str::fmi2Struct, args...; kwargs...) - -Wrapper for [`fmi2FreeFMUstate!`](@ref). - -See also [`fmiSetState`](@ref), [`fmiGetState`](@ref). -""" -function fmiFreeState!(str::fmi2Struct, args...; kwargs...) - fmi2FreeFMUstate!(str, args...; kwargs...) -end - -""" - fmiFreeState!(str::fmi3Struct, args...; kwargs...) - -Wrapper for [`fmi3FreeFMUState!`](@ref). - -See also [`fmiSetState`](@ref), [`fmiGetState`](@ref). -""" -function fmiFreeState!(str::fmi3Struct, args...; kwargs...) - fmi3FreeFMUState!(str, args...; kwargs...) -end - -""" - fmiSetState(str::fmi2Struct, args...; kwargs...) - -Wrapper for [`fmi2SetFMUstate`](@ref). - -See also [`fmiGetState`](@ref), [`fmiFreeState!`](@ref). -""" -function fmiSetState(str::fmi2Struct, args...; kwargs...) - fmi2SetFMUstate(str, args...; kwargs...) -end - -""" - fmiSetState(str::fmi3Struct, args...; kwargs...) - -Wrapper for [`fmi3SetFMUState`](@ref). - -See also [`fmiGetState`](@ref), [`fmiFreeState!`](@ref). -""" -function fmiSetState(str::fmi3Struct, args...; kwargs...) - fmi3SetFMUState(str, args...; kwargs...) -end - -""" - fmiGetDependencies(fmu::FMU2) - -Wrapper for [`fmi2GetDependencies`](@ref). -""" -function fmiGetDependencies(fmu::FMU2) - fmi2GetDependencies(fmu) -end - -""" - fmiGetDependencies(fmu::FMU3) - -Wrapper for [`fmi3GetDependencies`](@ref). -""" -function fmiGetDependencies(fmu::FMU3) - fmi3GetDependencies(fmu) -end - -""" - fmiStringToValueReference(dataStruct::Union{FMU2, fmi2ModelDescription}, identifier::Union{String, AbstractArray{String}}) - -Wrapper for [`fmi2StringToValueReference`](@ref). - -See also [`fmi2ValueReferenceToString`](@ref). -""" -function fmiStringToValueReference(dataStruct::Union{FMU2, fmi2ModelDescription}, identifier::Union{String, AbstractArray{String}}) - fmi2StringToValueReference(dataStruct, identifier) -end - -""" - fmiStringToValueReference(dataStruct::Union{FMU3, fmi3ModelDescription}, identifier::Union{String, AbstractArray{String}}) - -Wrapper for [`fmi3StringToValueReference`](@ref). - -See also [`fmi3ValueReferenceToString`](@ref). -""" -function fmiStringToValueReference(dataStruct::Union{FMU3, fmi3ModelDescription}, identifier::Union{String, AbstractArray{String}}) - fmi3StringToValueReference(dataStruct, identifier) -end - -""" - fmiGetModelName(str::fmi2StructMD) - -Return the `modelName` from `str`'s model description. - -Wrapper for [`fmi2GetModelName`](@ref). -""" -function fmiGetModelName(str::fmi2StructMD) - fmi2GetModelName(str) -end - -""" - fmiGetModelName(str::fmi3StructMD) - -Return the `modelName` from `str`'s model description. - -Wrapper for [`fmi3GetModelName`](@ref). -""" -function fmiGetModelName(str::fmi3StructMD) - fmi3GetModelName(str) -end - -# TODO call differently in fmi3: getInstantationToken -""" - fmiGetGUID(str::fmi2StructMD) - -Return the `guid` from `str`'s model description. - -Wrapper for [`fmi2GetGUID`](@ref). -""" -function fmiGetGUID(str::fmi2StructMD) - fmi2GetGUID(str) -end - -""" - fmiGetGenerationTool(str::fmi2StructMD) - -Returns the `generationtool` from `str`'s model description. - -Wrapper for [`fmi2GetGenerationTool`](@ref). -""" -function fmiGetGenerationTool(str::fmi2StructMD) - fmi2GetGenerationTool(str) -end - -""" - fmiGetGenerationTool(str::fmi3StructMD) - -Returns the `generationtool` from `str`'s model description. - -Wrapper for [`fmi3GetGenerationTool`](@ref). -""" -function fmiGetGenerationTool(str::fmi3StructMD) - fmi3GetGenerationTool(str) -end - -""" - fmiGetGenerationDateAndTime(str::fmi2StructMD) - -Returns the `generationdateandtime` from `str`'s model description. - -Wrapper for [`fmi2GetGenerationDateAndTime`](@ref). -""" -function fmiGetGenerationDateAndTime(str::fmi2StructMD) - fmi2GetGenerationDateAndTime(str) -end - -""" - fmiGetGenerationDateAndTime(str::fmi3StructMD) - -Returns the `generationdateandtime` from `str`'s model description. - -Wrapper for [`fmi3GetGenerationDateAndTime`](@ref). -""" -function fmiGetGenerationDateAndTime(str::fmi3StructMD) - fmi3GetGenerationDateAndTime(str) -end - -""" - fmiGetVariableNamingConvention(str::fmi2StructMD) - -Returns the `varaiblenamingconvention` from `str`'s model description. - -Wrapper for [`fmi2GetVariableNamingConvention`](@ref). -""" -function fmiGetVariableNamingConvention(str::fmi2StructMD) - fmi2GetVariableNamingConvention(str) -end - -""" - fmiGetVariableNamingConvention(str::fmi3StructMD) - -Returns the `varaiblenamingconvention` from `str`'s model description. - -Wrapper for [`fmi3GetVariableNamingConvention`](@ref). -""" -function fmiGetVariableNamingConvention(str::fmi3StructMD) - fmi3GetVariableNamingConvention(str) -end - -""" - fmiGetNumberOfEventIndicators(str::fmi2StructMD) - -Returns the `numberOfEventIndicators` from `str`'s model description. - -Wrapper for [`fmi2GetNumberOfEventIndicators`](@ref). -""" -function fmiGetNumberOfEventIndicators(str::fmi2StructMD) - fmi2GetNumberOfEventIndicators(str) -end - -""" - fmiGetNumberOfEventIndicators(str::fmi3StructMD) - -Returns the `numberOfEventIndicators` from `str`'s model description. - -Wrapper for [`fmi3GetNumberOfEventIndicators`](@ref). -""" -function fmiGetNumberOfEventIndicators(str::fmi3StructMD) - fmi3GetNumberOfEventIndicators(str) -end - -""" - fmiGetModelIdentifier(fmu::Union{FMU2, FMU3}) - -Returns the tag 'modelIdentifier' from CS or ME section. - -# Arguments - - `fmu::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `fmu::FMU3`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 3.0 Standard](https://fmi-standard.org/). -# Returns -- `fmu.modelDescription.coSimulation.modelIdentifier`: The function `fmiGetModelIdentifier` returns the tag 'coSimulation.modelIdentifier' from the model description of the FMU2 or FMU3-struct (`fmu.modelDescription`), if the FMU supports co simulation. -- `fmu.modelDescription.modelExchange.modelIdentifier`: The function `fmiGetModelIdentifier` returns the tag 'modelExchange.modelIdentifier' from the model description of the FMU2 or FMU3-struct (`fmu.modelDescription`), if the FMU supports model exchange -- `fmu.modelDescription.modelExchange.modelIdentifier`: The function `fmiGetModelIdentifier` returns the tag 'scheduledExecution.modelIdentifier' from the model description of the FMU3-struct (`fmu.modelDescription`), if the FMU supports scheduled execution - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - -Also see [`fmi2GetModelIdentifier`](@ref), [`FMU2`](@ref), [`fmi3GetModelIdentifier`](@ref), [`FMU3`](@ref). -""" -function fmiGetModelIdentifier(fmu::FMU2) - fmi2GetModelIdentifier(fmu.modelDescription; type=fmu.type) -end -function fmiGetModelIdentifier(fmu::FMU3) - fmi3GetModelIdentifier(fmu.modelDescription; type=fmu.type) -end -""" - fmiCanGetSetState(str::Union{fmi2StructMD, fmi3StructMD}) - -Returns true, if the FMU supports the getting/setting of states - -# Arguments -- `str::Union{fmi2StructMD, fmi3StructMD}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2StructMD = Union{FMU2, FMU2Component, fmi2ModelDescription}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::fmi2ModelDescription`: Struct witch provides the static information of ModelVariables. - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::fmi3ModelDescription`: Struct witch provides the static information of ModelVariables. - -# Returns - - `::Bool`: The function `fmi2CanGetSetState` returns True, if the FMU supports the getting/setting of states. - -# Source - - FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) - - FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files - - FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - - See also [`fmi2CanGetSetState`](@ref), [`fmi2StructMD`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi2ModelDescription`](@ref), [`fmi3CanGetSetState`](@ref), [`fmi3StructMD`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref), [`fmi3ModelDescription`](@ref). - """ -function fmiCanGetSetState(str::fmi2StructMD) - fmi2CanGetSetState(str) -end -function fmiCanGetSetState(str::fmi3StructMD) - fmi3CanGetSetState(str) -end - -""" - fmiCanSerializeFMUstate(str::Union{fmi2StructMD, fmi3StructMD}) - -Returns true, if the FMU state can be serialized - -# Arguments -- `str::Union{fmi2StructMD, fmi3StructMD}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2StructMD = Union{FMU2, FMU2Component, fmi2ModelDescription}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` -- `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::fmi2ModelDescription`: Struct wich provides the static information of ModelVariables. - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::fmi3ModelDescription`: Struct witch provides the static information of ModelVariables. - -# Returns - - `::Bool`: The function `fmi2CanSerializeFMUstate` returns True, if the FMU state can be serialized. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - -See also [`fmi2CanSerializeFMUstate`](@ref), [`fmi2StructMD`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi2ModelDescription`](@ref), [`fmi3CanSerializeFMUstate`](@ref), [`fmi3StructMD`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref), [`fmi3ModelDescription`](@ref). -""" -function fmiCanSerializeFMUstate(str::fmi2StructMD) - fmi2CanSerializeFMUstate(str) -end -function fmiCanSerializeFMUstate(str::fmi3StructMD) - fmi3CanSerializeFMUState(str) -end - -# TODO fmi3Call fmiProvidesDirectionalDerivatives - -""" - fmiProvidesDirectionalDerivative(str::Union{fmi2StructMD, fmi3StructMD}) - -Returns true, if the FMU provides directional derivatives - -# Arguments -- `str::Union{fmi2StructMD, fmi3StructMD}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2StructMD = Union{FMU2, FMU2Component, fmi2ModelDescription}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::fmi2ModelDescription`: Struct witch provides the static information of ModelVariables. - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::fmi3ModelDescription`: Struct witch provides the static information of ModelVariables. - -# Returns -- `::Bool`: The function `fmi2ProvidesDirectionalDerivative` returns True, if the FMU provides directional derivatives. - -See also [`fmi2ProvidesDirectionalDerivative`](@ref), [`fmi2StructMD`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi2ModelDescription`](@ref), [`fmi3ProvidesDirectionalDerivatives`](@ref), [`fmi3StructMD`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref), [`fmi3ModelDescription`](@ref). -""" -function fmiProvidesDirectionalDerivative(str::fmi2StructMD) - fmi2ProvidesDirectionalDerivative(str) -end -function fmiProvidesDirectionalDerivative(str::fmi3StructMD) - fmi3ProvidesDirectionalDerivatives(str) -end - -""" - fmiProvidesAdjointDerivative(str::fmi3StructMD) - -Returns true, if the FMU provides adjoint derivatives - -# Arguments -- `str::fmi3StructMD`: Representative for an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi3StructMD = Union{FMU3, FMU3Component, fmi3ModelDescription}` - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::fmi3ModelDescription`: Struct witch provides the static information of ModelVariables. - -# Returns -- `::Bool`: The function `fmi3ProvidesAdjointDerivatives` returns True, if the FMU provides adjoint derivatives. - -See also [`fmi3ProvidesAdjointDerivatves`](@ref), [`fmi3StructMD`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref), [`fmi3ModelDescription`](@ref). -""" -function fmiProvidesAdjointDerivative(str::fmi3StructMD) - fmi3ProvidesAdjointDerivatives(str) -end - -""" - fmiIsCoSimulation(str::Union{fmi2StructMD, fmi3StructMD}) - -Returns true, if the FMU supports co simulation - -# Arguments -- `str::Union{fmi2StructMD, fmi3StructMD}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2StructMD = Union{FMU2, FMU2Component, fmi2ModelDescription}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` -- `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::fmi2ModelDescription`: Struct witch provides the static information of ModelVariables. - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::fmi3ModelDescription`: Struct witch provides the static information of ModelVariables. - -# Returns - - `::Bool`: The function `fmi2IsCoSimulation` returns True, if the FMU supports co simulation - -See also [`fmi2IsCoSimulation`](@ref), [`fmi2StructMD`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi2ModelDescription`](@ref), [`fmi3IsCoSimulation`](@ref), [`fmi3StructMD`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref), [`fmi3ModelDescription`](@ref). -""" -function fmiIsCoSimulation(str::fmi2StructMD) - fmi2IsCoSimulation(str) -end -function fmiIsCoSimulation(str::fmi3StructMD) - fmi3IsCoSimulation(str) -end - -""" - fmiIsModelExchange(str::Union{fmi2StructMD, fmi3StructMD}) - -Returns true, if the FMU supports model exchange - -# Arguments -- `str::Union{fmi2StructMD, fmi3StructMD}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2StructMD = Union{FMU2, FMU2Component, fmi2ModelDescription}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::fmi2ModelDescription`: Struct witch provides the static information of ModelVariables. - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::fmi3ModelDescription`: Struct witch provides the static information of ModelVariables. - -# Returns - - `::Bool`: The function `fmi2IsModelExchange` returns True, if the FMU supports model exchange. - - # Source - - FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) - - FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files - - FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - -See also [`fmi2IsModelExchange`](@ref), [`fmi2StructMD`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi2ModelDescription`](@ref), [`fmi3IsModelExchange`](@ref), [`fmi3StructMD`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref), [`fmi3ModelDescription`](@ref). -""" -function fmiIsModelExchange(str::fmi2StructMD) - fmi2IsModelExchange(str) -end -function fmiIsModelExchange(str::fmi3StructMD) - fmi3IsModelExchange(str) -end - -""" - fmiIsScheduledExecution(str::fmi3StructMD) - -Returns true, if the FMU supports scheduled execution - -# Arguments -- `str::fmi3StructMD`: Representative for an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::fmi3ModelDescription`: Struct witch provides the static information of ModelVariables. - -# Returns - - `::Bool`: The function `fmi3IsScheduledExecution` returns True, if the FMU supports scheduled execution. - -See also [`fmi3IsScheduledExecution`](@ref), [`fmi3StructMD`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref), [`fmi3ModelDescription`](@ref). -""" -function fmiIsScheduledExecution(str::fmi3StructMD) - fmi3IsScheduledExecution(str) -end - -# Multiple Dispatch variants for FMUs with version 2.0.X - -""" - fmiLoad(pathToFMU::String; unpackPath=nothing, type=nothing) - -Load FMUs independent of the FMI version, currently supporting version 2.0.X and 3.0. - -# Arguments -- `pathToFMU::String`: String that contains the paths of ziped and unziped FMU folders. - -# Keywords -- `unpackPath=nothing`: Via optional argument ```unpackPath```, a path to unpack the FMU can be specified (default: system temporary directory). -- `type::Union{CS, ME, SE} = nothing`: Via ```type```, a FMU type can be selected. If none of the unified type set is used, the default value `type = nothing` will be used. - -# Returns -- Returns the instance of the FMU struct. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - - -See also [`fmi2Load`](@ref), [`fmi3Load`](@ref). -""" -function fmiLoad(pathToFMU::AbstractString, args...; kwargs...) - version = fmiCheckVersion(pathToFMU) - if version == "2.0" - fmi2Load(pathToFMU, args...; kwargs...) - elseif version == "3.0" - fmi3Load(pathToFMU, args...; kwargs...) - else - @warn "fmiLoad(...): Unknown FMU version" - end -end - -""" - fmiReload(fmu::Union{FMU2, FMU3}) - -Reloads the FMU-binary. This is useful, if the FMU does not support a clean reset implementation. - -# Arguments -- `fmu::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). -- `fmu::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -See also [`fmi2Reload`](@ref), [`fmi3Reload`](@ref). -""" -function fmiReload(fmu::FMU2, args...; kwargs...) - fmi2Reload(fmu, args...; kwargs...) -end -function fmiReload(fmu::FMU3, args...; kwargs...) - fmi3Reload(fmu, args...; kwargs...) -end - -""" - fmiSimulate(str::fmi2Struct, args...; kwargs...) - -Start a simulation of the FMU instance `str` for the matching FMU version and type. - -Wrapper for [`fmi2Simulate`](@ref). -""" -function fmiSimulate(str::fmi2Struct, args...; kwargs...) - fmi2Simulate(str, args...; kwargs...) -end - -""" - fmiSimulate(str::fmi3Struct, args...; kwargs...) - -Start a simulation of the FMU instance `str` for the matching FMU version and type. - -Wrapper for [`fmi3Simulate`](@ref). -""" -function fmiSimulate(str::fmi3Struct, args...; kwargs...) - fmi3Simulate(str, args...; kwargs...) -end - -""" - fmiSimulateCS(str::fmi2Struct, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing, args...; kwargs...) - -Start a simulation of the Co-Simulation FMU instance `str`. - -Wrapper for [`fmi2SimulateCS`](@ref). -""" -function fmiSimulateCS(str::fmi2Struct, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing, args...; kwargs...) - fmi2SimulateCS(str, tspan, args...; kwargs...) -end - -""" - fmiSimulateCS(str::fmi3Struct, args...; kwargs...) - -Start a simulation of the Co-Simulation FMU instance `str`. - -Wrapper for [`fmi3SimulateCS`](@ref). -""" -function fmiSimulateCS(str::fmi3Struct, args...; kwargs...) - fmi3SimulateCS(str, args...; kwargs...) -end - -""" - fmiSimulateME(str::Union{fmi2Struct,fmi3Struct}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - solver = nothing, - customFx = nothing, - recordValues::fmi2ValueReferenceFormat = nothing, - saveat = nothing, - x0::Union{AbstractArray{<:Real}, Nothing} = nothing, - setup::Union{Bool, Nothing} = nothing, - reset::Union{Bool, Nothing} = nothing, - instantiate::Union{Bool, Nothing} = nothing, - freeInstance::Union{Bool, Nothing} = nothing, - terminate::Union{Bool, Nothing} = nothing, - inputValueReferences::fmi2ValueReferenceFormat = nothing, - inputFunction = nothing, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, - dtmax::Union{Real, Nothing} = nothing, - callbacks = [], - showProgress::Bool = true, - kwargs...) - -Simulates a FMU instance for the given simulation time interval. - - -# Arguments -- `str::Union{fmi2StructMD, fmi3StructMD}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` -More detailed: `fmi3Struct = Union{FMU3, FMU3Instance}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - - `tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing`: Sets the time span as a tuple or the default value from the model description is used. - -# Keywords -- `tolerance::Union{Real, Nothing} = nothing`: Real number to set the tolerance for any OED-solver -- `dt::Union{Real, Nothing} = nothing`: Real number to set the step size of the OED-solver. Defaults to an automatic choice if the method is adaptive. More Info: [DifferentialEquations.jl Documentation](https://diffeq.sciml.ai/stable/basics/common_solver_opts/#Stepsize-Control) -- `solver = nothing`: Any Julia-supported OED-solver (default is Tsit5). More Info: [DifferentialEquations.jl Documentation](https://diffeq.sciml.ai/stable/solvers/ode_solve/#ode_solve) -- `customFx = nothing`: [deperecated] Ability to give a custom state derivative function xΜ‡=f(x,t) -- `recordValues::fmi2ValueReferenceFormat = nothing`: AbstractArray of variables (strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` -- `saveat = nothing`: Time points to save values at (interpolated). More Info: [DifferentialEquations.jl Documentation](https://diffeq.sciml.ai/stable/basics/common_solver_opts/#Output-Control) -- `x0::Union{AbstractArray{<:Real}, Nothing} = nothing`: Stores the specific value of `fmi2ScalarVariable` containing the modelVariables with the identical fmi2ValueReference to the input variable vr (vr = vrs[i]). And is therefore passed within prepareSolveFMU to fmi2Set , to set the start state. -- `setup::Bool = true`: Boolean, if FMU should be setup (default: setup=true) -- `reset::Union{Bool, Nothing} = nothing`: Boolean, if FMU should be reset before simulation (default: reset:=auto) -- `instantiate::Union{Bool, Nothing} = nothing`: Boolean value that decides whether to create a new instance of the specified fmu. -- `freeInstance::Union{Bool, Nothing} = nothing`: Boolean value that determines whether to dispose of the given instance, unload the loaded model, and free the allocated memory and other resources allocated by the FMU interface functions. -- `terminate::Union{Bool, Nothing} = nothing`: Boolean value that tells the FMU that the simulation run will be aborted. -- `inputValueReferences::fmi2ValueReferenceFormat = nothing`: AbstractArray of input variables (strings or variableIdentifiers) to set at every simulation step -- `inputFunction = nothing`: Function to retrieve the values to set the inputs to -- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dictionary of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization -- `dtmax::Union{Real, Nothing} = nothing`: Real number for setting maximum dt for adaptive timestepping for the ODE solver. The default values are package dependent. More Info: [DifferentialEquations.jl Documentation](https://diffeq.sciml.ai/stable/basics/common_solver_opts/#Stepsize-Control) -- `callbacks = []`: custom callbacks to add. -- `showProgress::Bool = true`: Boolean value that determines whether a progress bar is generated for a task -- `kwargs...`: Further parameters of already defined functions `solve(args..., kwargs...)` from the library [DifferentialEquations.jl](https://diffeq.sciml.ai/stable/#DifferentialEquations.jl:-Scientific-Machine-Learning-(SciML)-Enabled-Simulation-and-Estimation) - -# Returns -- If keyword `recordValues` is not set, a struct of type `ODESolution`. -- If keyword `recordValues` is set, a tuple of type (ODESolution, DiffEqCallbacks.SavedValues). - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - -See also [`fmi2SimulateME`](@ref) [`fmi2SimulateCS`](@ref), [`fmi2Simulate`](@ref), [`fmi2Struct`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref). - -""" -function fmiSimulateME(str::fmi2Struct, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing, args...; kwargs...) - fmi2SimulateME(str, tspan, args...; kwargs...) -end -function fmiSimulateME(str::fmi3Struct, args...; kwargs...) - fmi3SimulateME(str, args...; kwargs...) -end - -""" - fmiUnload(fmu::Union{FMU2, FMU3}) - -Unloads the FMU and all its instances and frees the allocated memory. - -# Arguments -- `fmu::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). -- `fmu::FMU3`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 3.0 Standard](https://fmi-standard.org/). - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -See also [`fmi2Unload`](@ref), [`fmi3Unload`](@ref). -""" -function fmiUnload(fmu::FMU2) - fmi2Unload(fmu) -end -function fmiUnload(fmu::FMU3) - fmi3Unload(fmu) -end - -#to add to docstring: see also [`fmi3GetNumberOfStates`](@ref) -""" - fmiGetNumberOfStates(str::Union{fmi2Struct, fmi3Struct}) - -Returns the number of states of the FMU. - -# Arguments -- `str::Union{fmi2Struct, fmi3Struct}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - -# Returns -- Returns the length of the `md.valueReferences::Array{fmi2ValueReference}` corresponding to the number of states of the FMU. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - -See also [`fmi2GetNumberOfStates`](@ref), [`fmi2Struct`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), , [`fmi3Struct`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref). -""" -function fmiGetNumberOfStates(str::fmi2Struct) - fmi2GetNumberOfStates(str) -end -function fmiGetNumberOfStates(str::fmi3Struct) - fmi3GetNumberOfStates(str) -end - -# TODO not in FMI3 -""" - fmiGetTypesPlatform(str::fmi2Struct) - -Returns the header file used to compile the FMU. By default returns `default`, version independent. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/). - -# Returns -- Returns the string to uniquely identify the β€œfmi2TypesPlatform.h” header file used for compilation of the functions of the FMU. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - -See also [`fmi2GetVersion`](@ref), [`fmi2Struct`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref). -""" -function fmiGetTypesPlatform(str::fmi2Struct) - fmi2GetTypesPlatform(str) -end - -""" - fmiGetVersion(str::Union{fmi2Struct, fmi3Struct}) - -Returns the version of the FMU, version independent. - -# Arguments -- `str::Union{fmi2Struct, fmi3Struct}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - -# Returns -- Returns a string from the address of a C-style (NUL-terminated) string. The string represents the version of the β€œfmiXFunctions.h” header file which was used to compile the functions of the FMU. The function returns β€œfmiVersion” which is defined in this header file. The standard header file as documented in this specification has version β€œ2.0” or "3.0" - -# Source - - FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) - - FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files - - FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - - FMISpec3.0[p. ]: 2.2.5. Inquire Version Number of Header Files - -See also [`fmi2GetVersion`](@ref), [`unsafe_string`](https://docs.julialang.org/en/v1/base/strings/#Base.unsafe_string), [`fmi2Struct`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi3GetVersion`](@ref), [`fmi3Struct`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref). -""" -function fmiGetVersion(str::fmi2Struct) - fmi2GetVersion(str) -end -function fmiGetVersion(str::fmi3Struct) - fmi3GetVersion(str) -end - -""" - fmiInfo(str::fmi2Struct) - -Prints FMU-specific information into the REPL. - -# Arguments -- `str::Union{fmi2Struct, fmi3Struct}`: Representative for an FMU in the [FMI 2.0.2 Standard](https://fmi-standard.org/) or [FMI 3.0 Standard](https://fmi-standard.org/). Other notation: -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` -More detailed: `fmi3StructMD = Union{FMU3, FMU3Instance, fmi3ModelDescription}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - - `str::FMU3`: Mutable struct representing an FMU in the [FMI 3.0 Standard](https://fmi-standard.org/). - - `str::FMU3Instance`: Mutable struct represents a pointer to an FMU specific data structure that contains the information needed. Also in [FMI 3.0 Standard](https://fmi-standard.org/). - -# Returns -- Prints FMU related information. - - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec3.0 Link: [https://fmi-standard.org/](https://fmi-standard.org/) - -See also [`fmi2Info`](@ref), [`fmi2Struct`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi3Info`](@ref), [`fmi3Struct`](@ref), [`FMU3`](@ref), [`FMU3Instance`](@ref). -""" -function fmiInfo(str::fmi2Struct) - fmi2Info(str) -end -function fmiInfo(str::fmi3Struct) - fmi3Info(str) -end - -""" - fmiGet(str::fmi2Struct, comp::FMU2Component, vrs::fmi2ValueReferenceFormat) - -Returns the specific value of `fmi2ScalarVariable` containing the modelVariables with the identical fmi2ValueReference in an array. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - - `vrs::fmi2ValueReferenceFormat`: wildcards for how a user can pass a fmi[X]ValueReference -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` - -# Returns -- `dstArray::Array{Any,1}(undef, length(vrs))`: Stores the specific value of `fmi2ScalarVariable` containing the modelVariables with the identical fmi2ValueReference to the input variable vr (vr = vrs[i]). `dstArray` is a 1-Dimensional Array that has the same length as `vrs`. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - -""" -function fmiGet(str::fmi2Struct, args...; kwargs...) - fmi2Get(str, args...; kwargs...) -end -function fmiGet(str::fmi3Struct, args...; kwargs...) - fmi3Get(str, args...; kwargs...) -end -""" - fmiGet!(str::fmi2Struct, comp::FMU2Component, vrs::fmi2ValueReferenceFormat, dstArray::AbstractArray) - -Stors the specific value of `fmi2ScalarVariable` containing the modelVariables with the identical fmi2ValueReference in an array. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` -- `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. -- `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `dstArray::AbstractArray`: Stores the specific value of `fmi2ScalarVariable` containing the modelVariables with the identical fmi2ValueReference to the input variable vr (vr = vrs[i]). `dstArray` has the same length as `vrs`. - -# Returns -- `retcodes::Array{fmi2Status}`: Returns an array of length length(vrs) with Type `fmi2Status`. Type `fmi2Status` is an enumeration and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - -""" -function fmiGet!(str::fmi2Struct, args...; kwargs...) - fmi2Get!(str, args...; kwargs...) -end -function fmiGet!(str::fmi3Struct, args...; kwargs...) - fmi3Get!(str, args...; kwargs...) -end -""" - fmiSet(str::fmi2Struct, comp::FMU2Component, vrs::fmi2ValueReferenceFormat, srcArray::AbstractArray; filter=nothing) - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` -- `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. -- `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `srcArray::AbstractArray`: Stores the specific value of `fmi2ScalarVariable` containing the modelVariables with the identical fmi2ValueReference to the input variable vr (vr = vrs[i]). `srcArray` has the same length as `vrs`. - -# Keywords -- `filter=nothing`: whether the individual values of "fmi2ScalarVariable" are to be stored - -# Returns -- `retcodes::Array{fmi2Status}`: Returns an array of length length(vrs) with Type `fmi2Status`. Type `fmi2Status` is an enumeration and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions -""" -function fmiSet(str::fmi2Struct, args...; kwargs...) - fmi2Set(str, args...; kwargs...) -end -function fmiSet(str::fmi3Struct, args...; kwargs...) - fmi3Set(str, args...; kwargs...) -end - -""" - fmiGetReal(str::fmi2Struct, vr::fmi2ValueReferenceFormat) - -Returns the real values of an array of variables - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: wildcards for how a user can pass a fmi[X]ValueReference -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` - -# Returns -- `values::Array{fm2Real}`: returns values of an array of fmi2Real variables with the dimension of fmi2ValueReferenceFormat length. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - -See also [`fmi2GetReal`](@ref),[`fmi2ValueReferenceFormat`](@ref), [`fmi2Struct`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref). - -""" -function fmiGetReal(str::fmi2Struct, args...; kwargs...) - fmi2GetReal(str, args...; kwargs...) -end -function fmiGetReal(str::fmi3Struct, args...; kwargs...) - fmi3GetReal(str, args...; kwargs...) -end - -export fmiGetReal - - -""" - fmiSampleJacobian(str::fmi2Struct, c::FMU2Component, - vUnknown_ref::Array{fmi2ValueReference}, - vKnown_ref::Array{fmi2ValueReference}, - steps::Array{fmi2Real} = ones(fmi2Real, length(vKnown_ref)).*1e-5) - fmiSampleJacobian(str::fmi2Struct, c::FMU2Component, - vUnknown_ref::AbstractArray{fmi2ValueReference}, - vKnown_ref::AbstractArray{fmi2ValueReference}, - steps::Union{AbstractArray{fmi2Real}, Nothing} = nothing) -This function samples the jacobian by manipulating corresponding values (central differences). -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vUnknown_ref::Array{fmi2ValueReference}`: Argument `vUnKnown_ref` contains values of type `fmi2ValueReference` which are identifiers of a variable value of the model.`vKnown_ref` is the Array of the vector values of Real input variables of function h that changes its value in the actual Mode. -- `vKnown_ref::Array{fmi2ValueReference}`: Argument `vKnown_ref` contains values of type `fmi2ValueReference` which are identifiers of a variable value of the model.`vKnown_ref` is the Array of the vector values of Real input variables of function h that changes its value in the actual Mode. -- `steps::Array{fmi2Real} = ones(fmi2Real, length(vKnown_ref)).*1e-5`: Predefined step size vector `steps`, where all entries have the value 1e-5. -- `steps::Union{AbstractArray{fmi2Real}, Nothing} = nothing`: Step size to be used for numerical differentiation. If nothing, a default value will be chosen automatically. - -# Returns -- `dvUnknown::Arrya{fmi2Real}`: -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -See also [`fmi2SampleJacobian`](@ref), [`fmi2Struct`](@ref), [`FMU2`](@ref), [`FMU2Component`](@ref), [`fmi2ValueReference`](@ref). -""" -function fmiSampleJacobian(str::fmi2Struct, args...; kwargs...) - fmi2SampleJacobian(str, args...; kwargs...) -end -function fmiSampleJacobian(str::fmi3Struct, args...; kwargs...) - fmi3SampleJacobian(str, args...; kwargs...) -end - -""" -#TODO -Samples the values of the jacobian (in-place). -""" -function fmiSampleJacobian!(str::fmi3Struct, args...; kwargs...) - fmi3SampleJacobian!(str, args...; kwargs...) -end -function fmiSampleJacobian!(str::fmi2Struct, args...; kwargs...) - fmi2SampleJacobian!(str, args...; kwargs...) -end - -""" - - fmiGetStartValue(s::fmi2Struct, vr::fmi2ValueReferenceFormat) - -Returns the start/default value for a given value reference. - - -# Arguments -- `md::fmi2ModelDescription`: Struct which provides the static information of ModelVariables. -- `vrs::fmi2ValueReferenceFormat = md.valueReferences`: wildcards for how a user can pass a fmi[X]ValueReference (default = md.valueReferences) -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` - -# Returns -- `starts::Array{fmi2ValueReferenceFormat}`: start/default value for a given value reference - -""" -function fmiGetStartValue(s::fmi2Struct, vr::fmi2ValueReferenceFormat) - fmi2GetStartValue(s, vr) -end -function fmiGetStartValue(s::fmi3Struct, vr::fmi3ValueReferenceFormat) - fmi3GetStartValue(s, vr) -end - -""" - fmiSaveSolution(solution::FMUSolution, filepath::AbstractString [; keyword="solution"]) - -Save a `solution` of an FMU simulation at `filepath`. - -Currently .mat, .jld2 and .csv are supported for saving and selected by the ending of `filepath`. -For JLD2 the `keyword` is used as key. -Loading a FMUSolution into FMI.jl is currently only possible for .jld2 files. - -See also [`fmiSaveSolutionCSV`](@ref), [`fmiSaveSolutionMAT`](@ref), [`fmiSaveSolutionJLD2`](@ref), [`fmiLoadSolutionJLD2`](@ref). -""" -function fmiSaveSolution(solution::FMUSolution, filepath::AbstractString; keyword="solution") - ending = split(filepath, ".")[2] - if ending == "mat" - fmiSaveSolutionMAT(solution, filepath) - elseif ending == "jld2" - fmiSaveSolutionJLD2(solution, filepath; keyword="solution") - elseif ending == "csv" - fmiSaveSolutionCSV(solution, filepath) - else - @assert false "This file format is currently not supported, please use *.mat, *.csv, *.JLD2" - end -end - -""" - fmiLoadSolution(filepath::AbstractString; keyword="solution") - -Wrapper for [`fmiLoadSolutionJLD2`](@ref). -""" -function fmiLoadSolution(filepath::AbstractString; keyword="solution") - ending = split(filepath, ".")[2] - if ending == "jld2" - fmiLoadSolutionJLD2(filepath; keyword="solution") - else - @warn "This file format is currently not supported, please use *.jld2" - end -end -export fmiSaveSolution, fmiLoadSolution - end # module FMI diff --git a/src/FMI2/additional.jl b/src/FMI2/additional.jl deleted file mode 100644 index d6be6c2c..00000000 --- a/src/FMI2/additional.jl +++ /dev/null @@ -1,168 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -# What is included in the file `FMI2_additional.jl` (FMU add functions)? -# - high-level functions, that are useful, but not part of the FMI-spec [exported] - -using Base.Filesystem: mktempdir - -using FMIImport: FMU2, fmi2ModelDescription -using FMIImport: fmi2Boolean, fmi2Real, fmi2Integer, fmi2Byte, fmi2String, fmi2FMUstate -using FMIImport: fmi2True, fmi2False -using FMIImport: fmi2StatusKind, fmi2Status -using FMIImport: fmi2DependencyKindDependent, fmi2DependencyKindFixed -using FMIImport: fmi2CallbackFunctions, fmi2Component -import FMIImport: fmi2VariableNamingConventionFlat, fmi2VariableNamingConventionStructured - -""" - fmi2VariableDependsOnVariable(fmu::FMU2, vr1::fmi2ValueReference, vr2::fmi2ValueReference) - -Return the dependence of the variable described by `vr1` on another variable described by `vr2` based on the model description of the `fmu`. - -See also [`fmi2GetDependencies`](@ref). -""" -function fmi2VariableDependsOnVariable(fmu::FMU2, vr1::fmi2ValueReference, vr2::fmi2ValueReference) - i1 = fmu.modelDescription.valueReferenceIndicies[vr1] - i2 = fmu.modelDescription.valueReferenceIndicies[vr2] - return fmi2GetDependencies(fmu)[i1, i2] -end - -""" - fmi2GetDependencies(fmu::FMU2) - -Build dependency `Matrix{Union{fmi2DependencyKind, Nothing}}` of dimension `n x n` for fast look-ups on dependencies between value references (`n` is number of states of the `fmu`). - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions - -See also [`fmi2PrintDependencies`](@ref), [`fmi2VariableDependsOnVariable`](@ref). -""" -function fmi2GetDependencies(fmu::FMU2) - if !isdefined(fmu, :dependencies) - dim = length(fmu.modelDescription.valueReferences) - @info "fmi2GetDependencies: Started building dependency matrix $(dim) x $(dim) ..." - - if fmi2DependenciesSupported(fmu.modelDescription) - fmu.dependencies = fill(nothing, dim, dim) - - for i in 1:dim - modelVariable = fmi2ModelVariablesForValueReference(fmu.modelDescription, fmu.modelDescription.valueReferences[i])[1] - - if modelVariable.dependencies !== nothing - indicies = collect(fmu.modelDescription.valueReferenceIndicies[fmu.modelDescription.modelVariables[dependency].valueReference] for dependency in modelVariable.dependencies) - dependenciesKind = modelVariable.dependenciesKind - - k = 1 - for j in 1:dim - if j in indicies - if dependenciesKind[k] == "fixed" - fmu.dependencies[i,j] = fmi2DependencyKindFixed - elseif dependenciesKind[k] == "dependent" - fmu.dependencies[i,j] = fmi2DependencyKindDependent - else - @warn "Unknown dependency kind for index ($i, $j) = `$(dependenciesKind[k])`." - end - k += 1 - end - end - end - end - else - fmu.dependencies = fill(nothing, dim, dim) - end - - @info "fmi2GetDependencies: Building dependency matrix $(dim) x $(dim) finished." - end - - fmu.dependencies -end - -""" - fmi2PrintDependencies(fmu::FMU2) - -Print the dependency matrix for `fmu` as returned by [`fmi2GetDependencies`](@ref). - -See also [`fmi2GetDependencies`](@ref). -""" -function fmi2PrintDependencies(fmu::FMU2) - dep = fmi2GetDependencies(fmu) - ni, nj = size(dep) - - for i in 1:ni - str = "" - for j in 1:nj - str = "$(str) $(Integer(dep[i,j]))" - end - println(str) - end -end - -""" - fmi2Info(fmu::FMU2) - -Print information about the `fmu`. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.4 Inquire Platform and Version Number of Header Files -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -""" -function fmi2Info(fmu::FMU2) - println("#################### Begin information for FMU ####################") - - println("\tModel name:\t\t\t$(fmi2GetModelName(fmu))") - println("\tFMI-Version:\t\t\t$(fmi2GetVersion(fmu))") - println("\tGUID:\t\t\t\t$(fmi2GetGUID(fmu))") - println("\tGeneration tool:\t\t$(fmi2GetGenerationTool(fmu))") - println("\tGeneration time:\t\t$(fmi2GetGenerationDateAndTime(fmu))") - print("\tVar. naming conv.:\t\t") - if fmi2GetVariableNamingConvention(fmu) == fmi2VariableNamingConventionFlat - println("flat") - elseif fmi2GetVariableNamingConvention(fmu) == fmi2VariableNamingConventionStructured - println("structured") - else - println("[unknown]") - end - println("\tEvent indicators:\t\t$(fmi2GetNumberOfEventIndicators(fmu))") - - println("\tInputs:\t\t\t\t$(length(fmu.modelDescription.inputValueReferences))") - for vr in fmu.modelDescription.inputValueReferences - println("\t\t$(vr) $(fmi2ValueReferenceToString(fmu, vr))") - end - - println("\tOutputs:\t\t\t$(length(fmu.modelDescription.outputValueReferences))") - for vr in fmu.modelDescription.outputValueReferences - println("\t\t$(vr) $(fmi2ValueReferenceToString(fmu, vr))") - end - - println("\tStates:\t\t\t\t$(length(fmu.modelDescription.stateValueReferences))") - for vr in fmu.modelDescription.stateValueReferences - println("\t\t$(vr) $(fmi2ValueReferenceToString(fmu, vr))") - end - - println("\tSupports Co-Simulation:\t\t$(fmi2IsCoSimulation(fmu))") - if fmi2IsCoSimulation(fmu) - println("\t\tModel identifier:\t$(fmu.modelDescription.coSimulation.modelIdentifier)") - println("\t\tGet/Set State:\t\t$(fmu.modelDescription.coSimulation.canGetAndSetFMUstate)") - println("\t\tSerialize State:\t$(fmu.modelDescription.coSimulation.canSerializeFMUstate)") - println("\t\tDir. Derivatives:\t$(fmu.modelDescription.coSimulation.providesDirectionalDerivative)") - - println("\t\tVar. com. steps:\t$(fmu.modelDescription.coSimulation.canHandleVariableCommunicationStepSize)") - println("\t\tInput interpol.:\t$(fmu.modelDescription.coSimulation.canInterpolateInputs)") - println("\t\tMax order out. der.:\t$(fmu.modelDescription.coSimulation.maxOutputDerivativeOrder)") - end - - println("\tSupports Model-Exchange:\t$(fmi2IsModelExchange(fmu))") - if fmi2IsModelExchange(fmu) - println("\t\tModel identifier:\t$(fmu.modelDescription.modelExchange.modelIdentifier)") - println("\t\tGet/Set State:\t\t$(fmu.modelDescription.modelExchange.canGetAndSetFMUstate)") - println("\t\tSerialize State:\t$(fmu.modelDescription.modelExchange.canSerializeFMUstate)") - println("\t\tDir. Derivatives:\t$(fmu.modelDescription.modelExchange.providesDirectionalDerivative)") - end - - println("##################### End information for FMU #####################") -end diff --git a/src/FMI2/comp_wraps.jl b/src/FMI2/comp_wraps.jl deleted file mode 100644 index 511ea875..00000000 --- a/src/FMI2/comp_wraps.jl +++ /dev/null @@ -1,618 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -# What is included in the file `FMI2_comp_wraps.jl` (FMU component wrappers)? -# - wrappers to call fmi2ComponentFunctions from FMUs (FMI-functions, last instantiated component is used) [exported] -# - wrappers to call fmi2ComponentFunctions from FMUs (additional functions, last instantiated component is used) [exported] - -# FMI-spec -""" - fmi2Simulate(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2Simulate(fmu::FMU2, c::Union{FMU2Component, Nothing}, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets passed as `nothing`) -""" -function fmi2Simulate(fmu::FMU2, args...; kwargs...) - return fmi2Simulate(fmu, nothing, args...; kwargs...) -end - -""" - fmi2SimulateCS(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SimulateCS(fmu::FMU2, c::Union{FMU2Component, Nothing}, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets passed as `nothing`) -""" -function fmi2SimulateCS(fmu::FMU2, args...; kwargs...) - return fmi2SimulateCS(fmu, nothing, args...; kwargs...) -end - -""" - fmi2SimulateME(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SimulateME(fmu::FMU2, c::Union{FMU2Component, Nothing}, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets passed as `nothing`) -""" -function fmi2SimulateME(fmu::FMU2, args...; kwargs...) - return fmi2SimulateME(fmu, nothing, args...; kwargs...) -end - -""" - fmi2FreeInstance!(fmu::FMU2) - -Wrapper for `fmi2FreeInstance!(c::FMU2Component; popComponent::Bool = true)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2FreeInstance!(fmu::FMU2) - fmi2FreeInstance!(getCurrentComponent(fmu)) # this command also removes the component from the array -end - -""" - fmi2SetDebugLogging(fmu::FMU2) - -Wrapper for `fmi2SetDebugLogging(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetDebugLogging(fmu::FMU2) - fmi2SetDebugLogging(getCurrentComponent(fmu)) -end - -""" - fmi2SetupExperiment(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetupExperiment(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetupExperiment(fmu::FMU2, args...; kwargs...) - fmi2SetupExperiment(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2EnterInitializationMode(fmu::FMU2) - -Wrapper for `fmi2EnterInitializationMode(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2EnterInitializationMode(fmu::FMU2) - fmi2EnterInitializationMode(getCurrentComponent(fmu)) -end - -""" - fmi2ExitInitializationMode(fmu::FMU2) - -Wrapper for `fmi2ExitInitializationMode(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2ExitInitializationMode(fmu::FMU2) - fmi2ExitInitializationMode(getCurrentComponent(fmu)) -end - -""" - fmi2Terminate(fmu::FMU2) - -Wrapper for `fmi2Terminate(c::FMU2Component; soft::Bool=false)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2Terminate(fmu::FMU2) - fmi2Terminate(getCurrentComponent(fmu)) -end - -""" - fmi2Reset(fmu::FMU2) - -Wrapper for `fmi2Reset(c::FMU2Component; soft::Bool=false)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2Reset(fmu::FMU2) - fmi2Reset(getCurrentComponent(fmu)) -end - -""" - fmi2GetReal(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetReal(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetReal(fmu::FMU2, args...; kwargs...) - fmi2GetReal(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetReal!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetReal!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetReal!(fmu::FMU2, args...; kwargs...) - fmi2GetReal!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2Get(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2Get(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2Get(fmu::FMU2, args...; kwargs...) - fmi2Get(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2Get!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2Get!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2Get!(fmu::FMU2, args...; kwargs...) - fmi2Get!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2Set(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2Set(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2Set(fmu::FMU2, args...; kwargs...) - fmi2Set(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetRealOutputDerivatives(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetRealOutputDerivatives(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetRealOutputDerivatives(fmu::FMU2, args...; kwargs...) - fmi2GetRealOutputDerivatives(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetReal(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetReal(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetReal(fmu::FMU2, args...; kwargs...) - fmi2SetReal(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetRealInputDerivatives(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetRealInputDerivatives(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetRealInputDerivatives(fmu::FMU2, args...; kwargs...) - fmi2SetRealInputDerivatives(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetInteger(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetInteger(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetInteger(fmu::FMU2, args...; kwargs...) - fmi2GetInteger(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetInteger!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetInteger!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetInteger!(fmu::FMU2, args...; kwargs...) - - fmi2GetInteger!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetInteger(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetInteger(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetInteger(fmu::FMU2, args...; kwargs...) - - fmi2SetInteger(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetBoolean(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetBoolean(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetBoolean(fmu::FMU2, args...; kwargs...) - - fmi2GetBoolean(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetBoolean!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetBoolean!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetBoolean!(fmu::FMU2, args...; kwargs...) - - fmi2GetBoolean!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetBoolean(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetBoolean(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetBoolean(fmu::FMU2, args...; kwargs...) - - fmi2SetBoolean(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetString(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetString(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetString(fmu::FMU2, args...; kwargs...) - - fmi2GetString(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetString!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetString!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetString!(fmu::FMU2, args...; kwargs...) - - fmi2GetString!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetString(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetString(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetString(fmu::FMU2, args...; kwargs...) - - fmi2SetString(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetFMUstate(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetFMUstate(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetFMUstate(fmu::FMU2, args...; kwargs...) - - fmi2GetFMUstate(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetFMUstate(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetFMUstate(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetFMUstate(fmu::FMU2, args...; kwargs...) - - fmi2SetFMUstate(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2FreeFMUstate!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2FreeFMUstate!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2FreeFMUstate!(fmu::FMU2, args...; kwargs...) - - fmi2FreeFMUstate!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SerializedFMUstateSize(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SerializedFMUstateSize(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SerializedFMUstateSize(fmu::FMU2, args...; kwargs...) - - fmi2SerializedFMUstateSize(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SerializeFMUstate(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SerializeFMUstate(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SerializeFMUstate(fmu::FMU2, args...; kwargs...) - - fmi2SerializeFMUstate(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2DeSerializeFMUstate(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2DeSerializeFMUstate(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2DeSerializeFMUstate(fmu::FMU2, args...; kwargs...) - - fmi2DeSerializeFMUstate(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetDirectionalDerivative!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetDirectionalDerivative!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetDirectionalDerivative!(fmu::FMU2, args...; kwargs...) - - fmi2GetDirectionalDerivative!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetDirectionalDerivative(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetDirectionalDerivative(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetDirectionalDerivative(fmu::FMU2, args...; kwargs...) - - fmi2GetDirectionalDerivative(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SampleDirectionalDerivative!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SampleDirectionalDerivative!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SampleDirectionalDerivative!(fmu::FMU2, args...; kwargs...) - - fmi2SampleDirectionalDerivative!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SampleDirectionalDerivative(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SampleDirectionalDerivative(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SampleDirectionalDerivative(fmu::FMU2, args...; kwargs...) - - fmi2SampleDirectionalDerivative(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetJacobian!(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetJacobian!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetJacobian!(fmu::FMU2, args...; kwargs...) - - fmi2GetJacobian!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetJacobian(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetJacobian(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetJacobian(fmu::FMU2, args...; kwargs...) - - fmi2GetJacobian(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2DoStep(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2DoStep(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2DoStep(fmu::FMU2, args...; kwargs...) - - fmi2DoStep(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2CancelStep(fmu::FMU2) - -Wrapper for `fmi2CancelStep(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2CancelStep(fmu::FMU2) - - fmi2CancelStep(getCurrentComponent(fmu)) -end - -""" - fmi2GetStatus(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetStatus!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetStatus(fmu::FMU2, args...; kwargs...) - - fmi2GetStatus!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetRealStatus(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetRealStatus!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetRealStatus(fmu::FMU2, args...; kwargs...) - - fmi2GetRealStatus!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetIntegerStatus(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetIntegerStatus!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetIntegerStatus(fmu::FMU2, args...; kwargs...) - - fmi2GetIntegerStatus!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetBooleanStatus(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetBooleanStatus!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetBooleanStatus(fmu::FMU2, args...; kwargs...) - - fmi2GetBooleanStatus!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetStringStatus(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetStringStatus!(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetStringStatus(fmu::FMU2, args...; kwargs...) - - fmi2GetStringStatus!(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetTime(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetTime(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetTime(fmu::FMU2, args...; kwargs...) - - fmi2SetTime(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2SetContinuousStates(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2SetContinuousStates(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2SetContinuousStates(fmu::FMU2, args...; kwargs...) - - fmi2SetContinuousStates(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2EnterEventMode(fmu::FMU2) - -Wrapper for `fmi2EnterEventMode(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2EnterEventMode(fmu::FMU2) - - fmi2EnterEventMode(getCurrentComponent(fmu)) -end - -""" - fmi2NewDiscreteStates(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2NewDiscreteStates(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2NewDiscreteStates(fmu::FMU2, args...; kwargs...) - - fmi2NewDiscreteStates(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2EnterContinuousTimeMode(fmu::FMU2) - -Wrapper for `fmi2EnterContinuousTimeMode(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2EnterContinuousTimeMode(fmu::FMU2) - - fmi2EnterContinuousTimeMode(getCurrentComponent(fmu)) -end - -""" - fmi2CompletedIntegratorStep(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2CompletedIntegratorStep(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2CompletedIntegratorStep(fmu::FMU2, args...; kwargs...) - - fmi2CompletedIntegratorStep(getCurrentComponent(fmu), args...; kwargs...) -end - -""" - fmi2GetDerivatives(fmu::FMU2) - -Wrapper for `fmi2GetDerivatives(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetDerivatives(fmu::FMU2) - - fmi2GetDerivatives(getCurrentComponent(fmu)) -end - -""" - fmi2GetEventIndicators(fmu::FMU2) - -Wrapper for `fmi2GetEventIndicators()` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetEventIndicators(fmu::FMU2) - - fmi2GetEventIndicators(getCurrentComponent(fmu)) -end - -""" - fmi2GetContinuousStates(fmu::FMU2)fmi2ins - -Wrapper for `fmi2GetContinuousStates(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetContinuousStates(fmu::FMU2) - - fmi2GetContinuousStates(getCurrentComponent(fmu)) -end - -""" - fmi2GetNominalsOfContinuousStates(fmu::FMU2) - -Wrapper for `fmi2GetNominalsOfContinuousStates(c::FMU2Component)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetNominalsOfContinuousStates(fmu::FMU2) - - fmi2GetNominalsOfContinuousStates(getCurrentComponent(fmu)) -end - -# additionals -""" - fmi2GetStartValue(fmu::FMU2, args...; kwargs...) - -Wrapper for `fmi2GetStartValue(c::FMU2Component, args...; kwargs...)` without a provided FMU2Component. -(Component `c` gets selected from `fmu`) -""" -function fmi2GetStartValue(fmu::FMU2, args...; kwargs...) - - fmi2GetStartValue(getCurrentComponent(fmu), args...; kwargs...) -end \ No newline at end of file diff --git a/src/FMI3/additional.jl b/src/FMI3/additional.jl deleted file mode 100644 index dce30415..00000000 --- a/src/FMI3/additional.jl +++ /dev/null @@ -1,175 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -# What is included in the file `FMI3_additional.jl` (FMU add functions)? -# - high-level functions, that are useful, but not part of the FMI-spec [exported] - -using Base.Filesystem: mktempdir - -using FMIImport: FMU3, fmi3ModelDescription -using FMIImport: fmi3Float32, fmi3Float64, fmi3Int8, fmi3Int16, fmi3Int32, fmi3Int64, fmi3Boolean, fmi3String, fmi3Binary, fmi3UInt8, fmi3UInt16, fmi3UInt32, fmi3UInt64, fmi3Byte -using FMIImport: fmi3Clock, fmi3FMUState -using FMIImport: fmi3True, fmi3False -using FMIImport: fmi3DependencyKindDependent, fmi3DependencyKindFixed -using FMIImport: fmi3CallbackLogger, fmi3CallbackIntermediateUpdate, fmi3CallbackClockUpdate, fmi3Instance -import FMIImport: fmi3VariableNamingConventionFlat, fmi3VariableNamingConventionStructured - -""" - fmi3VariableDependsOnVariable(fmu::FMU3, vr1::fmi3ValueReference, vr2::fmi3ValueReference) - -Return the dependence of the variable described by `vr1` on another variable described by `vr2` based on the model description of the `fmu`. - -See also [`fmi3GetDependencies`](@ref). -""" -function fmi3VariableDependsOnVariable(fmu::FMU3, vr1::fmi3ValueReference, vr2::fmi3ValueReference) - i1 = fmu.modelDescription.valueReferenceIndicies[vr1] - i2 = fmu.modelDescription.valueReferenceIndicies[vr2] - return fmi3GetDependencies(fmu)[i1, i2] -end - -""" - fmi3GetDependencies(fmu::FMU3) - -Build dependency `Matrix{Union{fmi3DependencyKind, Nothing}}` of dimension `n x n` for fast look-ups on dependencies between value references (`n` is number of states of the `fmu`). - -See also [`fmi3PrintDependencies`](@ref), [`fmi3VariableDependsOnVariable`](@ref). -""" -function fmi3GetDependencies(fmu::FMU3) - if !isdefined(fmu, :dependencies) - dim = length(fmu.modelDescription.valueReferences) - @info "fmi3GetDependencies: Started building dependency matrix $(dim) x $(dim) ..." - - if fmi3DependenciesSupported(fmu.modelDescription) - fmu.dependencies = fill(nothing, dim, dim) - - for i in 1:dim - modelVariable = fmi3ModelVariablesForValueReference(fmu.modelDescription, fmu.modelDescription.valueReferences[i])[1] - - if modelVariable.dependencies !== nothing - indicies = collect(fmu.modelDescription.valueReferenceIndicies[fmu.modelDescription.modelVariables[dependency].valueReference] for dependency in modelVariable.dependencies) - dependenciesKind = modelVariable.dependenciesKind - - k = 1 - for j in 1:dim - if j in indicies - if dependenciesKind[k] == "fixed" - fmu.dependencies[i,j] = fmi3DependencyKindFixed - elseif dependenciesKind[k] == "dependent" - fmu.dependencies[i,j] = fmi3DependencyKindDependent - else - @warn "Unknown dependency kind for index ($i, $j) = `$(dependenciesKind[k])`." - end - k += 1 - end - end - end - end - else - fmu.dependencies = fill(nothing, dim, dim) - end - - @info "fmi3GetDependencies: Building dependency matrix $(dim) x $(dim) finished." - end - - fmu.dependencies -end - -""" - fmi3PrintDependencies(fmu::FMU3) - -Print the dependency matrix for `fmu` as returned by [`fmi3GetDependencies`](@ref). - -See also [`fmi3GetDependencies`](@ref). -""" -function fmi3PrintDependencies(fmu::FMU3) - dep = fmi3GetDependencies(fmu) - ni, nj = size(dep) - - for i in 1:ni - str = "" - for j in 1:nj - str = "$(str) $(Integer(dep[i,j]))" - end - println(str) - end -end - -""" - fmi3Info(fmu::FMU3) - -Print information about the `fmu`. -""" -function fmi3Info(fmu::FMU3) - println("#################### Begin information for FMU ####################") - - println("\tModel name:\t\t\t$(fmi3GetModelName(fmu))") - println("\tFMI-Version:\t\t\t$(fmi3GetVersion(fmu))") - println("\tInstantiation Token:\t\t\t\t$(fmi3GetInstantiationToken(fmu))") - println("\tGeneration tool:\t\t$(fmi3GetGenerationTool(fmu))") - println("\tGeneration time:\t\t$(fmi3GetGenerationDateAndTime(fmu))") - print("\tVar. naming conv.:\t\t") - if fmi3GetVariableNamingConvention(fmu) == fmi3VariableNamingConventionFlat - println("flat") - elseif fmi3GetVariableNamingConvention(fmu) == fmi3VariableNamingConventionStructured - println("structured") - else - println("[unknown]") - end - println("\tEvent indicators:\t\t$(fmi3GetNumberOfEventIndicators(fmu))") - - println("\tInputs:\t\t\t\t$(length(fmu.modelDescription.inputValueReferences))") - for vr in fmu.modelDescription.inputValueReferences - println("\t\t$(vr) $(fmi3ValueReferenceToString(fmu, vr))") - end - - println("\tOutputs:\t\t\t$(length(fmu.modelDescription.outputValueReferences))") - for vr in fmu.modelDescription.outputValueReferences - println("\t\t$(vr) $(fmi3ValueReferenceToString(fmu, vr))") - end - - println("\tStates:\t\t\t\t$(length(fmu.modelDescription.stateValueReferences))") - for vr in fmu.modelDescription.stateValueReferences - println("\t\t$(vr) $(fmi3ValueReferenceToString(fmu, vr))") - end - - println("\tSupports Co-Simulation:\t\t$(fmi3IsCoSimulation(fmu))") - if fmi3IsCoSimulation(fmu) - println("\t\tModel identifier:\t$(fmu.modelDescription.coSimulation.modelIdentifier)") - println("\t\tGet/Set State:\t\t$(fmu.modelDescription.coSimulation.canGetAndSetFMUstate)") - println("\t\tSerialize State:\t$(fmu.modelDescription.coSimulation.canSerializeFMUstate)") - println("\t\tDir. Derivatives:\t$(fmu.modelDescription.coSimulation.providesDirectionalDerivatives)") - println("\t\tAdj. Derivatives:\t$(fmu.modelDescription.coSimulation.providesAdjointDerivatives)") - println("\t\tEvent Mode:\t$(fmu.modelDescription.coSimulation.hasEventMode)") - - println("\t\tVar. com. steps:\t$(fmu.modelDescription.coSimulation.canHandleVariableCommunicationStepSize)") - println("\t\tInput interpol.:\t$(fmu.modelDescription.coSimulation.canInterpolateInputs)") - println("\t\tMax order out. der.:\t$(fmu.modelDescription.coSimulation.maxOutputDerivativeOrder)") - end - - println("\tSupports Model-Exchange:\t$(fmi3IsModelExchange(fmu))") - if fmi3IsModelExchange(fmu) - println("\t\tModel identifier:\t$(fmu.modelDescription.modelExchange.modelIdentifier)") - println("\t\tGet/Set State:\t\t$(fmu.modelDescription.modelExchange.canGetAndSetFMUstate)") - println("\t\tSerialize State:\t$(fmu.modelDescription.modelExchange.canSerializeFMUstate)") - println("\t\tDir. Derivatives:\t$(fmu.modelDescription.modelExchange.providesDirectionalDerivatives)") - println("\t\tAdj. Derivatives:\t$(fmu.modelDescription.modelExchange.providesAdjointDerivatives)") - end - - println("\tSupports Scheduled-Execution:\t$(fmi3IsScheduledExecution(fmu))") - if fmi3IsScheduledExecution(fmu) - println("\t\tModel identifier:\t$(fmu.modelDescription.scheduledExecution.modelIdentifier)") - println("\t\tGet/Set State:\t\t$(fmu.modelDescription.scheduledExecution.canGetAndSetFMUstate)") - println("\t\tSerialize State:\t$(fmu.modelDescription.scheduledExecution.canSerializeFMUstate)") - println("\t\tNeeds Execution Tool:\t$(fmu.modelDescription.scheduledExecution.needsExecutionTool)") - println("\t\tInstantiated Once Per Process:\t$(fmu.modelDescription.scheduledExecution.canBeInstantiatedOnlyOncePerProcess)") - println("\t\tPer Element Dependencies:\t$(fmu.modelDescription.scheduledExecution.providesPerElementDependencies)") - - println("\t\tDir. Derivatives:\t$(fmu.modelDescription.scheduledExecution.providesDirectionalDerivatives)") - println("\t\tAdj. Derivatives:\t$(fmu.modelDescription.scheduledExecution.providesAdjointDerivatives)") - end - - println("##################### End information for FMU #####################") -end - diff --git a/src/FMI3/comp_wraps.jl b/src/FMI3/comp_wraps.jl deleted file mode 100644 index 437d356f..00000000 --- a/src/FMI3/comp_wraps.jl +++ /dev/null @@ -1,977 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -# What is included in the file `FMI3_comp_wraps.jl` (FMU instance wrappers)? -# - wrappers to call fmi3InstanceFunctions from FMUs (FMI-functions, last instantiated instance is used) [exported] -# - wrappers to call fmi3InstanceFunctions from FMUs (additional functions, last instantiated instance is used) [exported] - -# fmi-spec -""" - fmi3Simulate(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3Simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets passed as `nothing`) -""" -function fmi3Simulate(fmu::FMU3, args...; kwargs...) - return fmi3Simulate(fmu, nothing, args...; kwargs...) -end - -""" - fmi3SimulateCS(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SimulateCS(fmu::FMU3, c::Union{FMU3Instance, Nothing}, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets passed as `nothing`) -""" -function fmi3SimulateCS(fmu::FMU3, args...; kwargs...) - return fmi3SimulateCS(fmu, nothing, args...; kwargs...) -end - -""" - fmi3SimulateME(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SimulateME(fmu::FMU3, c::Union{FMU3Instance, Nothing}, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets passed as `nothing`) -""" -function fmi3SimulateME(fmu::FMU3, args...; kwargs...) - return fmi3SimulateME(fmu, nothing, args...; kwargs...) -end - -""" - fmi3FreeInstance!(fmu::FMU3) - -Wrapper for `fmi3FreeInstance!(c::FMU3Instance; popInstance::Bool = true)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3FreeInstance!(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3FreeInstance!(fmu.instances[end]) # this command also removes the instance from the array -end - -""" - fmi3SetDebugLogging(fmu::FMU3) - -Wrapper for `fmi3SetDebugLogging(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetDebugLogging(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetDebugLogging(fmu.instances[end]) -end - -""" - fmi3EnterInitializationMode(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3EnterInitializationMode(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3EnterInitializationMode(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3EnterInitializationMode(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3ExitInitializationMode(fmu::FMU3) - -Wrapper for `fmi3ExitInitializationMode(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3ExitInitializationMode(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3ExitInitializationMode(fmu.instances[end]) -end - -""" - fmi3Terminate(fmu::FMU3) - -Wrapper for `fmi3Terminate(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3Terminate(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3Terminate(fmu.instances[end]) -end - -""" - fmi3Reset(fmu::FMU3) - -Wrapper for `fmi3Reset(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3Reset(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3Reset(fmu.instances[end]) -end - -""" - fmi3GetFloat32(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetFloat32(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetFloat32(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetFloat32(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetFloat32!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetFloat32!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetFloat32!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetFloat32!(fmu.instances[end], args...; kwargs...) -end - -""" -fmi3SetFloat32(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetFloat32(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetFloat32(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetFloat32(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetFloat64(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetFloat64(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetFloat64(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetFloat64(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetFloat64!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetFloat64!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetFloat64!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetFloat64!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetFloat64(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetFloat64(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetFloat64(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetFloat64(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt8(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt8(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt8(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt8(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt8!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt8!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt8!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt8!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetInt8(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetInt8(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetInt8(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetInt8(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt8(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt8(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt8(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt8(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt8!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt8!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt8!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt8!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetUInt8(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetUInt8(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetUInt8(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetUInt8(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt16(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt16(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt16(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt16(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt16!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt16!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt16!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt16!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetInt16(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetInt16(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetInt16(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetInt16(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt16(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt16(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt16(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt16(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt16!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt16!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt16!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt16!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetUInt16(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetUInt16(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetUInt16(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetUInt16(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt32(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt32(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt32(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt32(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt32!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt32!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt32!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt32!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetInt32(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetInt32(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetInt32(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetInt32(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt32(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt32(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt32(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt32(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt32!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt32!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt32!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt32!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetUInt32(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetUInt32(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetUInt32(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetUInt32(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt64(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt64(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt64(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt64(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetInt64!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetInt64!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetInt64!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetInt64!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetInt64(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetInt64(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetInt64(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetInt64(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt64(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt64(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt64(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt64(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetUInt64!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetUInt64!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetUInt64!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetUInt64!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetUInt64(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetUInt64(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetUInt64(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetUInt64(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetBoolean(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetBoolean(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetBoolean(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetBoolean(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetBoolean!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetBoolean!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetBoolean!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetBoolean!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetBoolean(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetBoolean!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetBoolean(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetBoolean(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetString(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetString(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetString(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetString(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetString!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetString!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetString!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetString!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetString(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetString(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetString(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetString(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetBinary(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetBinary(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetBinary(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetBinary(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetBinary!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetBinary!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetBinary!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetBinary!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetBinary(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetBinary(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetBinary(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetBinary(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetClock(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetClock(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetClock(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetClock(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetClock!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetClock!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetClock!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetClock!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetClock(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetClock(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetClock(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetClock(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3Get(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3Get(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3Get(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3Get(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3Get!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3Get!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3Get!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3Get!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3Set(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3Set(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3Set(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3Set(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetFMUstate(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetFMUstate(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetFMUState(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetFMUState(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetFMUState(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetFMUState(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetFMUState(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetFMUState(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3FreeFMUState!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3FreeFMUState!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3FreeFMUState!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3FreeFMUState!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SerializedFMUStateSize(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SerializedFMUStateSize(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SerializedFMUStateSize(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SerializedFMUStateSize(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SerializeFMUState(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SerializeFMUState(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SerializeFMUState(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SerializeFMUState(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3DeSerializeFMUState(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3DeSerializeFMUState(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3DeSerializeFMUState(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3DeSerializeFMUState(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetDirectionalDerivative(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetDirectionalDerivative(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetDirectionalDerivative(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetDirectionalDerivative(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetDirectionalDerivative!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetDirectionalDerivative!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetDirectionalDerivative!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetDirectionalDerivative!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetAdjointDerivative(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetAdjointDerivative(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetAdjointDerivative(fmu::FMU3, args...; kwargs...) - - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetAdjointDerivative(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetAdjointDerivative!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetAdjointDerivative!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetAdjointDerivative!(fmu::FMU3, args...; kwargs...) - - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetAdjointDerivative!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SampleDirectionalDerivative!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SampleDirectionalDerivative!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SampleDirectionalDerivative!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SampleDirectionalDerivative!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SampleDirectionalDerivative(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SampleDirectionalDerivative(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SampleDirectionalDerivative(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SampleDirectionalDerivative(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetJacobian!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetJacobian!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetJacobian!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetJacobian!(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetJacobian(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetJacobian(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetJacobian(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetJacobian(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetOutputDerivatives(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetOutputDerivatives(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetOutputDerivatives(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetOutputDerivatives(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3EnterConfigurationMode(fmu::FMU3) - -Wrapper for `fmi3EnterConfigurationMode(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3EnterConfigurationMode(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3EnterConfigurationMode(fmu.instances[end]) -end - -""" - fmi3GetNumberOfContinuousStates(fmu::FMU3) - -Wrapper for `fmi3GetNumberOfContinuousStates(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetNumberOfContinuousStates(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetNumberOfContinuousStates(fmu.instances[end]) -end - -""" - fmi3GetNumberOfVariableDependencies(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetNumberOfVariableDependencies(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetNumberOfVariableDependencies(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetNumberOfVariableDependencies(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetVariableDependencies(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetVariableDependencies(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetVariableDependencies(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetVariableDependencies(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3GetContinuousStates(fmu::FMU3) - -Wrapper for `fmi3GetContinuousStates(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetContinuousStates(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetContinuousStates(fmu.instances[end]) -end - -""" - fmi3GetNominalsOfContinuousStates(fmu::FMU3) - -Wrapper for `fmi3GetNominalsOfContinuousStates(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetNominalsOfContinuousStates(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetNominalsOfContinuousStates(fmu.instances[end]) -end - -""" -fmi3EvaluateDiscreteStates(fmu::FMU3) - -Wrapper for `fmi3EvaluateDiscreteStates(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3EvaluateDiscreteStates(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3EvaluateDiscreteStates(fmu.instances[end]) -end - -""" - fmi3UpdateDiscreteStates(fmu::FMU3) - -Wrapper for `fmi3UpdateDiscreteStates(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3UpdateDiscreteStates(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3UpdateDiscreteStates(fmu.instances[end]) -end - -""" - fmi3EnterContinuousTimeMode(fmu::FMU3) - -Wrapper for `fmi3EnterContinuousTimeMode(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3EnterContinuousTimeMode(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3EnterContinuousTimeMode(fmu.instances[end]) -end - -""" - fmi3EnterStepMode(fmu::FMU3) - -Wrapper for `fmi3EnterStepMode(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3EnterStepMode(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3EnterStepMode(fmu.instances[end]) -end - -""" - fmi3ExitConfigurationMode(fmu::FMU3) - -Wrapper for `fmi3ExitConfigurationMode(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3ExitConfigurationMode(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3ExitConfigurationMode(fmu.instances[end]) -end - -""" - fmi3SetTime(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetTime(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetTime(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetTime(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3SetContinuousStates(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3SetContinuousStates(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3SetContinuousStates(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3SetContinuousStates(fmu.instances[end], args...; kwargs...) -end - -""" -fmi3GetContinuousStateDerivatives(fmu::FMU3) - -Wrapper for `fmi3GetContinuousStateDerivatives(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetContinuousStateDerivatives(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetContinuousStateDerivatives(fmu.instances[end]) -end - -""" - fmi3GetEventIndicators(fmu::FMU3) - -Wrapper for `fmi3GetEventIndicators(c::FMU3Instance)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetEventIndicators(fmu::FMU3) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetEventIndicators(fmu.instances[end]) -end - -""" -fmi3CompletedIntegratorStep(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3CompletedIntegratorStep(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3CompletedIntegratorStep(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3CompletedIntegratorStep(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3EnterEventMode(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3EnterEventMode(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3EnterEventMode(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3EnterEventMode(fmu.instances[end], args...; kwargs...) -end - -""" - fmi3DoStep!(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3DoStep!(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3DoStep!(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3DoStep!(fmu.instances[end], args...; kwargs...) -end - - -""" - fmi3GetStartValue(fmu::FMU3, args...; kwargs...) - -Wrapper for `fmi3GetStartValue(c::FMU3Instance, args...; kwargs...)` without a provided FMU3Instance. -(Instance `c` gets selected from `fmu`) -""" -function fmi3GetStartValue(fmu::FMU3, args...; kwargs...) - @assert length(fmu.instances) > 0 ["No FMU instance allocated, have you already called fmiInstantiate?"] - fmi3GetStartValue(fmu.instances[end], args...; kwargs...) -end \ No newline at end of file diff --git a/src/assertions.jl b/src/assertions.jl deleted file mode 100644 index f28cf1a7..00000000 --- a/src/assertions.jl +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -@enum errorType begin - unsupportedFMU - unknownFMUType - unknown -end - -# Format the fmi2Status into a String -function errorTypeString(type::errorType) - fname = StackTraces.stacktrace()[3].func # index 3 to step into calling function! - - if type == unsupportedFMU - return "$fname() doesn't support FMUs with this version." - elseif type == unknownFMUType - return "Unknown FMU type in $fname(), is neigther CS nor ME." - end - - "Unknown Assertion in $fname()." -end - -function assert(cond::Bool, type::errorType = unknown) - @assert cond [errorTypeString(type)] -end - -function error(type::errorType = unknown) - @assert false [errorTypeString(type)] -end diff --git a/src/check.jl b/src/check.jl deleted file mode 100644 index 22a303cd..00000000 --- a/src/check.jl +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMIImport.EzXML -using FMIImport.ZipFile - -function fmiCheckVersion(pathToFMU::String; unpackPath=nothing) - # Unzip MD - - # Download FMU if necessary - if startswith(pathToFMU, "http") - @info "Downloading FMU for Version extraction from `$(pathToFMU)`." - pathToFMU = download(pathToFMU) - end - - pathToFMU = normpath(pathToFMU) - - fileNameExt = basename(pathToFMU) - (fileName, fileExt) = splitext(fileNameExt) - - if unpackPath === nothing - # cleanup=true leads to issues with automatic testing on linux server. - unpackPath = mktempdir(; prefix="fmijl_", cleanup=false) - end - - zipPath = joinpath(unpackPath, fileName * ".zip") - unzippedPath = joinpath(unpackPath, fileName) - - # only copy ZIP if not already there - if !isfile(zipPath) - cp(pathToFMU, zipPath; force=true) - end - - @assert isfile(zipPath) ["fmiCheckVersion(...): ZIP-Archive couldn't be copied to `$zipPath`."] - - zipAbsPath = isabspath(zipPath) ? zipPath : joinpath(pwd(), zipPath) - unzippedAbsPath = isabspath(unzippedPath) ? unzippedPath : joinpath(pwd(), unzippedPath) - - @assert isfile(zipAbsPath) ["fmiCheckVersion(...): Can't deploy ZIP-Archive at `$(zipAbsPath)`."] - - # only unzip if not already done - if !isdir(unzippedAbsPath) - mkpath(unzippedAbsPath) - - zarchive = ZipFile.Reader(zipAbsPath) - for f in zarchive.files - if f.name == "modelDescription.xml" - fileAbsPath = normpath(joinpath(unzippedAbsPath, f.name)) - - # create directory if not forced by zip file folder - mkpath(dirname(fileAbsPath)) - - numBytes = write(fileAbsPath, read(f)) - - @assert numBytes > 0 "fmiCheckVersion(...): Can't unzip file `$(f.name)` at `$(fileAbsPath)`, file is empty." - @assert isfile(fileAbsPath) "fmiCheckVersion(...): Can't unzip file `$(f.name)` at `$(fileAbsPath)`, file does not exist in target directory." - end - - end - close(zarchive) - end - - @assert isdir(unzippedAbsPath) ["fmiCheckVersion(...): ZIP-Archive couldn't be unzipped at `$(unzippedPath)`."] - # @info "fmiUnzipVersion(...): Successfully unzipped modelDescription.xml at `$unzippedAbsPath`." - - # read version tag - - doc = readxml(normpath(joinpath(unzippedAbsPath, "modelDescription.xml"))) - - root = doc.root - version = root["fmiVersion"] - - # cleanup unzipped modelDescription - try - rm(unzippedAbsPath; recursive = true, force = true) - rm(zipAbsPath; recursive = true, force = true) - catch e - @warn "Cannot delete unpacked data on disc. Maybe some files are opened in another application." - end - - # return version - return version -end \ No newline at end of file diff --git a/src/deprecated.jl b/src/deprecated.jl index dd88d2e4..3556435b 100644 --- a/src/deprecated.jl +++ b/src/deprecated.jl @@ -3,1511 +3,96 @@ # Licensed under the MIT license. See LICENSE file in the project root for details. # -""" -DEPRECATED -fmiInstantiate!(fmu::FMU2; pushComponents::Bool = true, visible::Bool = false, loggingOn::Bool = false, externalCallbacks::Bool = false, - logStatusOK::Bool=true, logStatusWarning::Bool=true, logStatusDiscard::Bool=true, logStatusError::Bool=true, logStatusFatal::Bool=true, logStatusPending::Bool=true) - -Creates a new instance of the FMU, version independent. - -Create a new instance of the given fmu, adds a logger if logginOn == true. - -# Arguments -- `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - -# Keywords -- `pushComponents::Bool = true`: `pushComponents` if the item `component` should be inserted in `fmu.components`(default = `true`). -- `visible::Bool = false`: `visible` if the FMU should be started with graphic interface, if supported (default=`false`) -- `loggingOn::Bool = false`: `loggingOn` if the FMU should log and display function calls (default=`false`) -- `externalCallbacks::Bool = false`: `externalCallbacks` if an external DLL should be used for the fmi2CallbackFunctions, this may improve readability of logging messages (default=`false`) -- `logStatusOK::Bool=true`: `logStatusOK` whether to log status of kind `fmi2OK` (default=`true`) -- `logStatusWarning::Bool=true`: `logStatusWarning` whether to log status of kind `fmi2Warning` (default=`true`) -- `logStatusDiscard::Bool=true`: `logStatusDiscard` whether to log status of kind `fmi2Discard` (default=`true`) -- `logStatusError::Bool=true`: `logStatusError` whether to log status of kind `fmi2Error` (default=`true`) -- `logStatusFatal::Bool=true`: `logStatusFatal` whether to log status of kind `fmi2Fatal` (default=`true`) -- `logStatusPending::Bool=true`: `logStatusPending` whether to log status of kind `fmi2Pending` (default=`true`) - -# Returns -- `nothing`: if the instantiation failed. In addition, an error message appears. -- `component`: Returns the instance of a new FMU component. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.19]: 2.1.5 Creation, Destruction and Logging of FMU Instances - - -""" -function fmiInstantiate!(fmu::FMU2, args...; kwargs...) - fmi2Instantiate!(fmu, args...; kwargs...) -end -export fmiInstantiate! - -""" -DEPRECATED - fmiFreeInstance!(str::fmi2Struct) - -Frees the allocated memory of the last instance of the FMU. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiFreeInstance!(str::fmi2Struct) - fmi2FreeInstance!(str) -end -export fmiFreeInstance! - -""" -DEPRECATED fmiSetDebugLogging(str::fmi2Struct) - -Control the use of the logging callback function, version independent. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.22]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.22]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.22]: 2.1.5 Creation, Destruction and Logging of FMU Instances - -""" -function fmiSetDebugLogging(str::fmi2Struct) - fmi2SetDebugLogging(str) -end -export fmiSetDebugLogging - -""" -DEPRECATED - fmiSetupExperiment(str::fmi2Struct, c::FMU2Component, startTime::Union{Real, Nothing} = nothing, stopTime::Union{Real, Nothing} = nothing; tolerance::Union{Real, Nothing} = nothing) - -Initialize the Simulation boundries - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `startTime::Union{Real, Nothing} = nothing`: `startTime` is a real number which sets the value of starting time of the experiment. The default value is set automatically if doing nothing (default = `nothing`). -- `stopTime::Union{Real, Nothing} = nothing`: `stopTime` is a real number which sets the value of ending time of the experiment. The default value is set automatically if doing nothing (default = `nothing`). - -# Keywords -- `tolerance::Union{Real, Nothing} = nothing`: `tolerance` is a real number which sets the value of tolerance range. The default value is set automatically if doing nothing (default = `nothing`). - -# Returns -- Returns a warning if `str.state` is not called in `fmi2ComponentStateInstantiated`. -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiSetupExperiment(str::fmi2Struct, args...; kwargs...) - fmi2SetupExperiment(str, args...; kwargs...) -end -export fmiSetupExperiment - -""" -DEPRECATED - fmiEnterInitializationMode(str::fmi2Struct) - -Informs the FMU to enter initializaton mode, version independent. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- Returns a warning if `str.state` is not called in `fmi2ComponentStateInstantiated`. -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiEnterInitializationMode(str::fmi2Struct) - fmi2EnterInitializationMode(str) -end -export fmiEnterInitializationMode - -""" -DEPRECATED - fmiExitInitializationMode(str::fmi2Struct) - -Informs the FMU to exit initialization mode, version independent. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- Returns a warning if `str.state` is not called in `fmi2ComponentStateInitializationMode`. -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiExitInitializationMode(str::fmi2Struct) - fmi2ExitInitializationMode(str) -end -export fmiExitInitializationMode - -""" -DEPRECATED - fmiTerminate(str::fmi2Struct) - -Informs the FMU that the simulation run is terminated, version independent. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- Returns a warning if `str.state` is not called in `fmi2ComponentStateContinuousTimeMode` or `fmi2ComponentStateEventMode`. -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - - - -""" -function fmiTerminate(str::fmi2Struct) - fmi2Terminate(str) -end -export fmiTerminate - -""" -DEPRECATED - fmiReset(str::fmi2Struct) - -Resets the FMU after a simulation run, version independent. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- Returns a warning if `str.state` is not called in `fmi2ComponentStateTerminated` or `fmi2ComponentStateError`. -- Returns an error if the reinstantiation failed. -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.23]: 2.1.6 Initialization, Termination, and Resetting an FMU -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - - -""" -function fmiReset(str::fmi2Struct) - fmi2Reset(str) -end -export fmiReset - -""" -DEPRECATED - fmi2GetRealOutputDerivatives(c::FMU2Component, vr::fmi2ValueReferenceFormat, order::AbstractArray{fmi2Integer}) - - -Sets the n-th time derivative of real input variables. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::Array{fmi2ValueReference}`: Argument `vr` is an array of `nvr` value handels called "ValueReference" that define the variables whose derivatives shall be set. -- `order::Array{fmi2Integer}`: Argument `order` is an array of fmi2Integer values witch specifys the corresponding order of derivative of the real input variable. -- - -# Returns -- `value::AbstactArray{fmi2Integer}`: Return `value` is an array which represents a vector with the values of the derivatives. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.104]: 4.2.1 Transfer of Input / Output Values and Parameters - - -""" -DEPRECATED -function fmiGetRealOutputDerivatives(str::fmi2Struct, args...; kwargs...) - fmi2GetRealOutputDerivatives(str, args...; kwargs...) -end -export fmiGetRealOutputDerivatives - -""" -DEPRECATED - fmiGetReal!(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Array{fmi2Real}) - - fmiGetReal!(str::fmi2Struct, c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, value::Array{fmi2Real}) - -Writes the real values of an array of variables in the given field - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Wildcards for how a user can pass a fmi[X]ValueReference -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Argument `vr` is an array of `nvr` value handels called "ValueReference" that define the variable that shall be inquired. -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Array{fm2Real}`: Argument `values` is an array with the actual values of these variables. -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiGetReal!(str::fmi2Struct, args...; kwargs...) - fmi2GetReal!(str, args...; kwargs...) -end -export fmiGetReal! - -""" -DEPRECATED - fmiSetReal(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Union{Array{<:Real}, <:Real}) - - fmiSetReal(str::fmi2Struct, c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, value::Array{fmi2Real}) - -Set the values of an array of real variables - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Wildcards for how a user can pass a fmi[X]ValueReference -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Argument `vr` is an array of `nvr` value handels called "ValueReference" that define the variable that shall be inquired. -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Union{Array{<:Real}, <:Real}`: Argument `values` is an array with the actual values of these variables. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiSetReal(str::fmi2Struct, args...; kwargs...) - fmi2SetReal(str, args...; kwargs...) -end -export fmiSetReal - -""" -DEPRECATED#Todo: Add types according spec - - fmiSetRealInputDerivatives(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, order, values) - - fmiSetRealInputDerivatives(str::fmi2Struct, c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, order::Array{fmi2Integer}, value::Array{fmi2Real}) - -Sets the n-th time derivative of real input variables. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Argument `vr` is an array of `nvr` value handels called "ValueReference" that define the variable that shall be inquired. -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `order::Array{fmi2Integer}`: Argument `order` is an array of fmi2Integer values witch specifys the corresponding order of derivative of the real input variable. -- `values::Array{fmi2Real}`: Argument `values` is an array with the actual values of these variables. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.104]: 4.2.1 Transfer of Input / Output Values and Parameters - - -""" -function fmiSetRealInputDerivatives(str::fmi2Struct, args...; kwargs...) - fmi2SetRealInputDerivatives(str, args...; kwargs...) -end -export fmiSetRealInputDerivatives - -""" -DEPRECATED - fmiGetInteger(str::fmi2Struct,c::FMU2Component, vr::fmi2ValueReferenceFormat) - -Returns the integer values of an array of variables - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` - -# Returns -- `values::Array{fmi2Integer}`: Return `values` is an array with the actual values of these variables. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - - -""" -function fmiGetInteger(str::fmi2Struct,args...; kwargs...) - fmi2GetInteger(str, args...; kwargs...) -end -export fmiGetInteger - -""" -DEPRECATED - function fmiGetInteger!(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Array{fmi2Integer}) - - function fmiGetInteger!(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Array{fmi2Integer}) - -Writes the integer values of an array of variables in the given field - -fmi2GetInteger! is only possible for arrays of values, please use an array instead of a scalar. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Argument `vr` is an array of `nvr` value handels called "ValueReference" that define the variable that shall be inquired. -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Array{fmi2Integer}`: Argument `values` is an array with the actual values of these variables. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - - -""" -function fmiGetInteger!(str::fmi2Struct, args...; kwargs...) - fmi2GetInteger!(str, args...; kwargs...) -end -export fmiGetInteger! - -""" -DEPRECATED - fmiSetInteger(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Union{Array{<:Integer}, <:Integer}) - - fmiSetInteger(str::fmi2Struct, c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, value::Array{fmi2Integer}) - -Set the values of an array of integer variables - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Argument `vr` is an array of `nvr` value handels called "ValueReference" that define the variable that shall be inquired. -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Union{Array{<:Integer}, <:Integer}`: Argument `values` is an array or a single value with type Integer or any subtyp -- `value::Array{fmi2Integer}`: Argument `values` is an array with the actual values of these variables. -# Returns -- `status::fmi2Status`: Return `status` indicates the success of the function call. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiSetInteger(str::fmi2Struct, args...; kwargs...) - fmi2SetInteger(str, args...; kwargs...) -end -export fmiSetInteger - -""" -DEPRECATED - fmiGetBoolean(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat) - -Returns the boolean values of an array of variables - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` - -# Returns -- `values::Array{fmi2Boolean}`: Return `values` is an array with the actual values of these variables. - -""" -function fmiGetBoolean(str::fmi2Struct, args...; kwargs...) - fmi2GetBoolean(str, args...; kwargs...) -end -export fmiGetBoolean - -""" -DEPRECATED - fmiGetBoolean!(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Array{fmi2Boolean}) - -Writes the boolean values of an array of variables in the given field - -fmi2GetBoolean! is only possible for arrays of values, please use an array instead of a scalar. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Argument `vr` is an array of `nvr` value handels called "ValueReference" that define the variable that shall be inquired. -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Union{Array{<:Integer}, <:Integer}`: Argument `values` is an array or a single value with type Integer or any subtyp -- `value::Array{fmi2Integer}`: Argument `values` is an array with the actual values of these variables. -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - -""" -function fmiGetBoolean!(str::fmi2Struct, args...; kwargs...) - fmi2GetBoolean!(str, args...; kwargs...) -end -export fmiGetBoolean! - -""" -DEPRECATED - fmiSetBoolean(str::fmi2Struct, c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, value::Array{fmi2Boolean}) - - fmiSetBoolean(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Union{Array{Bool}, Bool}) - -Set the values of an array of boolean variables - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Array of the FMI2 Data Typ `fmi2ValueReference` -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Union{Array{Bool}, Bool}`: Argument `values` is an array or a single value with type Boolean or any subtyp -- `value::Array{fmi2Boolean}`: Argument `values` is an array with the actual values of these variables. -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - -""" -function fmiSetBoolean(str::fmi2Struct, args...; kwargs...) - fmi2SetBoolean(str, args...; kwargs...) -end -export fmiSetBoolean - -""" -DEPRECATED - fmiGetString(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat) - -Returns the string values of an array of variables - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` - -# Returns -- `values::Array{fmi2String}`: Return `values` is an array with the actual values of these variables. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - - -""" -function fmiGetString(str::fmi2Struct, args...; kwargs...) - fmi2GetString(str, args...; kwargs...) -end -export fmiGetString - -""" -DEPRECATED - fmiGetString!(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Array{fmi2String}) - - fmiGetString!(str::fmi2Struct, c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, value::Vector{Ptr{Cchar}}) - -Writes the string values of an array of variables in the given field - -These functions are especially used to get the actual values of output variables if a model is connected with other -models. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Array of the FMI2 Data Typ `fmi2ValueReference` -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Union{Array{Bool}, Bool}`: Argument `values` is an array or a single value with type Boolean or any subtyp. -- `value::Vector{Ptr{Cchar}}`: Argument `values` is an vector with the actual values of these variables. -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions - -""" -function fmiGetString!(str::fmi2Struct, args...; kwargs...) - fmi2GetString!(str, args...; kwargs...) -end -export fmiGetString! - -""" -DEPRECATED - fmiSetString(str::fmi2Struct, c::FMU2Component, vr::fmi2ValueReferenceFormat, values::Union{Array{String}, String}) - - fmiSetString(str::fmi2Struct, c::FMU2Component, vr::Array{fmi2ValueReference}, nvr::Csize_t, value::Union{Array{Ptr{Cchar}}, Array{Ptr{UInt8}}}) - -Set the values of an array of string variables - -For the exact rules on which type of variables fmi2SetXXX -can be called see FMISpec2.0.2 section 2.2.7 , as well as FMISpec2.0.2 section 3.2.3 in case of ModelExchange and FMISpec2.0.2 section 4.2.4 in case of -CoSimulation. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vr::fmi2ValueReferenceFormat`: Argument `vr` defines the value references of the variables. -More detailed: `fmi2ValueReferenceFormat = Union{Nothing, String, Array{String,1}, fmi2ValueReference, Array{fmi2ValueReference,1}, Int64, Array{Int64,1}, Symbol}` -- `vr::Array{fmi2ValueReference}`: Array of the FMI2 Data Typ `fmi2ValueReference` -- `nvr::Csize_t`: Argument `nvr` defines the size of `vr`. -- `values::Union{Array{String}, String}`: Argument `values` is an array or a single value with type String. -- `value::Vector{Ptr{Cchar}}`: Argument `values` is an vector with the actual values of these variables. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions -- FMISpec2.0.2[p.18]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.24]: 2.1.7 Getting and Setting Variable Values -- FMISpec2.0.2[p.46]: 2.2.7 Definition of Model Variables -- FMISpec2.0.2[p.46]: 3.2.3 State Machine of Calling Sequence -- FMISpec2.0.2[p.108]: 4.2.4 State Machine of Calling Sequence from Master to Slave - -""" -function fmiSetString(str::fmi2Struct, args...; kwargs...) - fmi2SetString(str, args...; kwargs...) +function warnDeprecated(oldStr, newStr, additional="") + @warn "`$(oldStr)` is deprecated, use `$(newStr)` instead. $(additional)\n(this message is printed 3 times)." maxlog=3 end -export fmiSetString - -""" -DEPRECATED - fmiSerializedFMUstateSize(str::fmi2Struct, c::FMU2Component, state::fmi2FMUstate) - - -Returns the size of the byte vector in which the FMUstate can be stored. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `state::fmi2FMUstate`: Argument `state` is a pointer to a data structure in the FMU that saves the internal FMU state of the actual or a previous time instant. - -# Returns -- Return `size` is an object that safely references a value of type `Csize_t`. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.25]: 2.1.8 Getting and Setting the Complete FMU State - - -""" -function fmiSerializedFMUstateSize(str::fmi2Struct, args...; kwargs...) - fmi2SerializedFMUstateSize(str, args...; kwargs...) +function fmi2Simulate(args...; kwargs...) + warnDeprecated("fmi2Simulate", "simulate") + simulate(args...; kwargs...) end -export fmiSerializedFMUstateSize - -""" -DEPRECATED - fmiSerializeFMUstate(str::fmi2Struct, c::FMU2Component, state::fmi2FMUstate) - -Serializes the data referenced by the pointer FMUstate and copies this data into the byte vector serializedState of length size to be provided by the environment. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `state::fmi2FMUstate`: Argument `state` is a pointer to a data structure in the FMU that saves the internal FMU state of the actual or a previous time instant. +export fmi2Simulate -# Returns -- `serialized:: Array{fmi2Byte}`: Return `serializedState` contains the copy of the serialized data referenced by the pointer FMUstate - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.25]: 2.1.8 Getting and Setting the Complete FMU State - - -""" -function fmiSerializeFMUstate(str::fmi2Struct, args...; kwargs...) - fmi2SerializeFMUstate(str, args...; kwargs...) +function fmiSimulate(args...; kwargs...) + warnDeprecated("fmiSimulate", "simulate") + simulate(args...; kwargs...) end -export fmiSerializeFMUstate - -""" -DEPRECATEDTODO - fmiDeSerializeFMUstate(str::fmi2Struct, c::FMU2Component, serializedState::Array{fmi2Byte}) - -Deserialize the data in the serializedState fmi2Byte field +export fmiSimulate -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `serializedState::Array{fmi2Byte}`: Argument `serializedState` contains the fmi2Byte field to be deserialized. - -# Returns -- Return `state` is a pointer to a copy of the internal FMU state. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.25]: 2.1.8 Getting and Setting the Complete FMU State - - -""" -function fmiDeSerializeFMUstate(str::fmi2Struct, args...; kwargs...) - fmi2DeSerializeFMUstate(str, args...; kwargs...) +function fmi2SimulateME(args...; kwargs...) + warnDeprecated("fmi2SimulateME", "simulateME", "FMI version is determined automatically.") + simulateME(args...; kwargs...) end -export fmiDeSerializeFMUstate - -""" -DEPRECATED - fmiGetDirectionalDerivative(str::fmi2Struct, c::FMU2Component, - vUnknown_ref::AbstractArray{fmi2ValueReference}, - vKnown_ref::AbstractArray{fmi2ValueReference}, - dvKnown::Union{AbstractArray{fmi2Real}, Nothing} = nothing) - - fmi2GetDirectionalDerivative(str::fmi2Struct, c::FMU2Component, - vUnknown_ref::fmi2ValueReference, - vKnown_ref::fmi2ValueReference, - dvKnown::fmi2Real = 1.0) - -The Wrapper Function and the Direct function call to compute the partial derivative with respect to `vKnown_ref`. - -Computes the directional derivatives of an FMU. An FMU has different Modes and in every Mode an FMU might be described by different equations and different unknowns.The precise definitions are given in the mathematical descriptions of Model Exchange (section 3.1) and Co-Simulation (section 4.1). In every Mode, the general form of the FMU equations are: -𝐯_unknown = 𝐑(𝐯_known, 𝐯_rest) - -- `v_unknown`: vector of unknown Real variables computed in the actual Mode: - - Initialization Mode: unkowns kisted under `` that have type Real. - - Continuous-Time Mode (ModelExchange): The continuous-time outputs and state derivatives. (= the variables listed under `` with type Real and variability = `continuous` and the variables listed as state derivatives under `)`. - - Event Mode (ModelExchange): The same variables as in the Continuous-Time Mode and additionally variables under `` with type Real and variability = `discrete`. - - Step Mode (CoSimulation): The variables listed under `` with type Real and variability = `continuous` or `discrete`. If `` is present, also the variables listed here as state derivatives. -- `v_known`: Real input variables of function h that changes its value in the actual Mode. -- `v_rest`:Set of input variables of function h that either changes its value in the actual Mode but are non-Real variables, or do not change their values in this Mode, but change their values in other Modes - -Computes a linear combination of the partial derivatives of h with respect to the selected input variables 𝐯_known: - - Ξ”v_unknown = (Ξ΄h / Ξ΄v_known) Ξ”v_known +export fmi2SimulateME -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vUnknown_ref::AbstractArray{fmi2ValueReference}`: Argument `vUnknown_ref` contains values of type`fmi2ValueReference` which are identifiers of a variable value of the model. `vUnknown_ref` can be equated with `v_unknown`(variable described above). - - `vUnknown_ref::fmi2ValueReference`: Argument `vUnknown_ref` contains a value of type`fmi2ValueReference` which is an identifier of a variable value of the model. `vUnknown_ref` can be equated with `v_unknown`(variable described above). -- `vKnown_ref::AbstractArray{fmi2ValueReference}`: Argument `vKnown_ref` contains values of type `fmi2ValueReference` which are identifiers of a variable value of the model.`vKnown_ref` can be equated with `v_known`(variable described above). -- `vKnown_ref::fmi2ValueReference`: Argument `vKnown_ref` contains a value of type`fmi2ValueReference` which is an identifier of a variable value of the model. `vKnown_ref` can be equated with `v_known`(variable described above). -- `dvKnown::Union{AbstractArray{fmi2Real}, Nothing} = nothing`: If no seed vector is passed the value `nothing` is used. The vector values Compute the partial derivative with respect to the given entries in vector `vKnown_ref` with the matching evaluate of `dvKnown`. -- `dvKnown::Fmi2Real = 1.0`: If no seed value is passed the value `dvKnown = 1.0` is used. Compute the partial derivative with respect to `vKnown_ref` with the value `dvKnown = 1.0`. # gehΓΆrt das zu den v_rest values - -# Returns -- `dvUnknown::Array{fmi2Real}`: Return `dvUnknown` contains the directional derivative vector values. - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.25]: 2.1.9 Getting Partial Derivatives - -""" -function fmiGetDirectionalDerivative(str::fmi2Struct, args...; kwargs...) - fmi2GetDirectionalDerivative(str, args...; kwargs...) +function fmiSimulateME(args...; kwargs...) + warnDeprecated("fmiSimulateME", "simulateME") + simulateME(args...; kwargs...) end -export fmiGetDirectionalDerivative - -""" -DEPRECATEDTODO -> Arguments - fmiGetDirectionalDerivative!(str::fmi2Struct, c::FMU2Component, - vUnknown_ref::AbstractArray{fmi2ValueReference}, - vKnown_ref::AbstractArray{fmi2ValueReference}, - dvUnknown::AbstractArray, - dvKnown::Union{Array{fmi2Real}, Nothing} = nothing) - - fmiGetDirectionalDerivative!(str::fmi2Struct, c::FMU2Component, - vUnknown_ref::AbstractArray{fmi2ValueReference}, - nUnknown::Csize_t, - vKnown_ref::AbstractArray{fmi2ValueReference}, - nKnown::Csize_t, - dvKnown::AbstractArray{fmi2Real}, - dvUnknown::AbstractArray) - - -Wrapper Function call to compute the partial derivative with respect to the variables `vKnown_ref`. - -Computes the directional derivatives of an FMU. An FMU has different Modes and in every Mode an FMU might be described by different equations and different unknowns.The precise definitions are given in the mathematical descriptions of Model Exchange (section 3.1) and Co-Simulation (section 4.1). In every Mode, the general form of the FMU equations are: -𝐯_unknown = 𝐑(𝐯_known, 𝐯_rest) - -- `v_unknown`: vector of unknown Real variables computed in the actual Mode: - - Initialization Mode: unkowns kisted under `` that have type Real. - - Continuous-Time Mode (ModelExchange): The continuous-time outputs and state derivatives. (= the variables listed under `` with type Real and variability = `continuous` and the variables listed as state derivatives under `)`. - - Event Mode (ModelExchange): The same variables as in the Continuous-Time Mode and additionally variables under `` with type Real and variability = `discrete`. - - Step Mode (CoSimulation): The variables listed under `` with type Real and variability = `continuous` or `discrete`. If `` is present, also the variables listed here as state derivatives. -- `v_known`: Real input variables of function h that changes its value in the actual Mode. -- `v_rest`:Set of input variables of function h that either changes its value in the actual Mode but are non-Real variables, or do not change their values in this Mode, but change their values in other Modes - -Computes a linear combination of the partial derivatives of h with respect to the selected input variables 𝐯_known: +export fmiSimulateME - Ξ”v_unknown = (Ξ΄h / Ξ΄v_known) Ξ”v_known - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `vUnknown_ref::AbstracArray{fmi2ValueReference}`: Argument `vUnknown_ref` contains values of type`fmi2ValueReference` which are identifiers of a variable value of the model. `vUnknown_ref` can be equated with `v_unknown`(variable described above). -- `vKnown_ref::AbstractArray{fmi2ValueReference}`: Argument `vKnown_ref` contains values of type `fmi2ValueReference` which are identifiers of a variable value of the model.`vKnown_ref` can be equated with `v_known`(variable described above). -- `dvUnknown::AbstractArray`: Stores the directional derivative vector values. -- `dvKnown::Union{Array{fmi2Real}, Nothing} = nothing`: If no seed vector is passed the value `nothing` is used. The vector values Compute the partial derivative with respect to the given entries in vector `vKnown_ref` with the matching evaluate of `dvKnown`. -- `dvKnown::AbstractArray{fmi2Real}`:The vector values Compute the partial derivative with respect to the given entries in vector `vKnown_ref` with the matching evaluate of `dvKnown`. -- `nUnknown::Csize_t`: -- `nKnown::Csize_t`: - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.25]: 2.1.9 Getting Partial Derivatives - -""" -function fmiGetDirectionalDerivative!(str::fmi2Struct, args...; kwargs...) - fmi2GetDirectionalDerivative!(str, args...; kwargs...) +function fmi2SimulateCS(args...; kwargs...) + warnDeprecated("fmi2SimulateCS", "simulateCS", "FMI version is determined automatically.") + simulateCS(args...; kwargs...) end -export fmiGetDirectionalDerivative! - -""" -DEPRECATED - fmiDoStep(str::fmi2Struct, c::FMU2Component, communicationStepSize::Union{Real, Nothing} = nothing; currentCommunicationPoint::Union{Real, Nothing} = nothing, noSetFMUStatePriorToCurrentPoint::Bool = true) - - fmiDoStep(str::fmi2Struct, c::FMU2Component, currentCommunicationPoint::fmi2Real, communicationStepSize::fmi2Real, noSetFMUStatePriorToCurrentPoint::fmi2Boolean) - -Does one step in the CoSimulation FMU - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `communicationStepSize::Union{Real, Nothing} = nothing`: Argument `communicationStepSize` contains a value of type `Real` or `Nothing` , if no argument is passed the default value `nothing` is used. `communicationStepSize` defines the communiction step size. -- `currentCommunicationPoint::fmi2Real`: Argument `currentCommunicationPoint` contains a value of type `fmi2Real` which is a identifier for a variable value . `currentCommunicationPoint` defines the current communication point of the master. -- `communicationStepSize::fmi2Real`: Argument `communicationStepSize` contains a value of type `fmi2Real` which is a identifier for a variable value. `communicationStepSize` defines the communiction step size. -- `noSetFMUStatePriorToCurrentPoint::fmi2Boolean`: Argument `noSetFMUStatePriorToCurrentPoint` contains a value of type `fmi2Boolean` which is a identifier for a variable value. `noSetFMUStatePriorToCurrentPoint` indicates whether `fmi2SetFMUState`will no longer be called for time instants prior to `currentCommunicationPoint` in this simulation run. - -# Keywords -- `currentCommunicationPoint::Union{Real, Nothing} = nothing`: Argument `currentCommunicationPoint` contains a value of type `Real` or type `Nothing`. If no argument is passed the default value `nothing` is used. `currentCommunicationPoint` defines the current communication point of the master. -- `noSetFMUStatePriorToCurrentPoint::Bool = true`: Argument `noSetFMUStatePriorToCurrentPoint` contains a value of type `Boolean`. If no argument is passed the default value `true` is used. `noSetFMUStatePriorToCurrentPoint` indicates whether `fmi2SetFMUState` is no longer called for times before the `currentCommunicationPoint` in this simulation run Simulation run. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.104]: 4.2.2 Computation +export fmi2SimulateCS - -""" -function fmiDoStep(str::fmi2Struct, args...; kwargs...) - fmi2DoStep(str, args...; kwargs...) +function fmiSimulateCS(args...; kwargs...) + warnDeprecated("fmiSimulateCS", "simulateCS") + simulateCS(args...; kwargs...) end -export fmiDoStep - -""" -DEPRECATED - fmiSetTime(c::fmi2Struct, c::FMU2Component, time::fmi2Real) - - fmiSetTime(c::fmi2Struct, c::FMU2Component, t::Real) - -Set a new time instant and re-initialize caching of variables that depend on time. - -# Arguments -- `c::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `c::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `c::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `time::fmi2Real`: Argument `time` contains a value of type `fmi2Real` which is a alias type for `Real` data type. `time` sets the independent variable time t. -- `t::Real`: Argument `t` contains a value of type `Real`. `t` sets the independent variable time t. +export fmiSimulateCS -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.1 Providing Independent Variables and Re-initialization of Caching - -""" -function fmiSetTime(c::fmi2Struct, args...; kwargs...) - fmi2SetTime(c, args...; kwargs...) +function fmiLoad(args...; kwargs...) + warnDeprecated("fmiLoad", "loadFMU") + loadFMU(args...; kwargs...) end -export fmiSetTime - -""" -DEPRECATED - fmiSetContinuousStates(str::fmi2Struct, c::FMU2Component, - x::AbstractArray{fmi2Real}, - nx::Csize_t) - - fmiSetContinuousStates(str::fmi2Struct, c::FMU2Component, - x::Union{AbstractArray{Float32},AbstractArray{Float64}}) - -Set a new (continuous) state vector +export fmiLoad -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `x::AbstractArray{fmi2Real}`: Argument `x` contains values of type `fmi2Real` which is a alias type for `Real` data type.`x` is the `AbstractArray` of the vector values of `Real` input variables of function h that changes its value in the actual Mode. -- `x::Union{AbstractArray{Float32},AbstractArray{Float64}}`: -- `nx::Csize_t`: Argument `nx` defines the length of vector `x` and is provided for checking purposes - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.1 Providing Independent Variables and Re-initialization of Caching - -""" -function fmiSetContinuousStates(str::fmi2Struct, args...; kwargs...) - fmi2SetContinuousStates(str, args...; kwargs...) +function fmi2Load(args...; kwargs...) + warnDeprecated("fmi2Load", "loadFMU", "FMI version is determined automatically.") + loadFMU(args...; kwargs...) end -export fmiSetContinuousStates - -""" -DEPRECATED - fmi2EnterEventMode(str::fmi2Struct) - -The model enters Event Mode from the Continuous-Time Mode and discrete-time equations may become active (and relations are not β€œfrozen”). - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously +export fmi2Load -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations - -""" -function fmi2EnterEventMode(str::fmi2Struct) - fmi2EnterEventMode(str) +function fmi3Load(args...; kwargs...) + warnDeprecated("fmi3Load", "loadFMU", "FMI version is determined automatically.") + loadFMU(args...; kwargs...) end -export fmi2EnterEventMode - -""" -DEPRECATED - fmiNewDiscreteStates(str::fmi2Struct) - -Returns the next discrete states - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- `eventInfo::fmi2EventInfo*`: Strut with `fmi2Boolean` Variables -More detailed: - - `newDiscreteStatesNeeded::fmi2Boolean`: If `newDiscreteStatesNeeded = fmi2True` the FMU should stay in Event Mode, and the FMU requires to set new inputs to the FMU to compute and get the outputs and to call -fmi2NewDiscreteStates again. If all FMUs return `newDiscreteStatesNeeded = fmi2False` call fmi2EnterContinuousTimeMode. - - `terminateSimulation::fmi2Boolean`: If `terminateSimulation = fmi2True` call `fmi2Terminate` - - `nominalsOfContinuousStatesChanged::fmi2Boolean`: If `nominalsOfContinuousStatesChanged = fmi2True` then the nominal values of the states have changed due to the function call and can be inquired with `fmi2GetNominalsOfContinuousStates`. - - `valuesOfContinuousStatesChanged::fmi2Boolean`: If `valuesOfContinuousStatesChanged = fmi2True`, then at least one element of the continuous state vector has changed its value due to the function call. The new values of the states can be retrieved with `fmi2GetContinuousStates`. If no element of the continuous state vector has changed its value, `valuesOfContinuousStatesChanged` must return fmi2False. - - `nextEventTimeDefined::fmi2Boolean`: If `nextEventTimeDefined = fmi2True`, then the simulation shall integrate at most until `time = nextEventTime`, and shall call `fmi2EnterEventMode` at this time instant. If integration is stopped before nextEventTime, the definition of `nextEventTime` becomes obsolete. - - `nextEventTime::fmi2Real`: next event if `nextEventTimeDefined=fmi2True` -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations +export fmi3Load -""" -function fmiNewDiscreteStates(str::fmi2Struct) - fmi2NewDiscreteStates(str) +function fmiUnload(args...; kwargs...) + warnDeprecated("fmiUnload", "unloadFMU") + unloadFMU(args...; kwargs...) end -export fmiNewDiscreteStates +export fmiUnload -""" -DEPRECATED - fmiEnterContinuousTimeMode(str::fmi2Struct) - -The model enters Continuous-Time Mode and all discrete-time equations become inactive and all relations are β€œfrozen”. -This function has to be called when changing from Event Mode into Continuous-Time Mode. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously - -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations - -""" -function fmiEnterContinuousTimeMode(str::fmi2Struct) - fmi2EnterContinuousTimeMode(str) +function fmi2Unload(args...; kwargs...) + warnDeprecated("fmi2Unload", "unloadFMU", "FMI version is determined automatically.") + unloadFMU(args...; kwargs...) end -export fmiEnterContinuousTimeMode +export fmi2Unload -""" -DEPRECATED - fmiCompletedIntegratorStep(str::fmi2Struct, c::FMU2Component, noSetFMUStatePriorToCurrentPoint::fmi2Boolean) - -This function must be called by the environment after every completed step - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -- `noSetFMUStatePriorToCurrentPoint::fmi2Boolean`: Argument `noSetFMUStatePriorToCurrentPoint = fmi2True` if `fmi2SetFMUState` will no longer be called for time instants prior to current time in this simulation run. - -# Returns -- `status::fmi2Status`: Return `status` is an enumeration of type `fmi2Status` and indicates the success of the function call. -More detailed: - - `fmi2OK`: all well - - `fmi2Warning`: things are not quite right, but the computation can continue - - `fmi2Discard`: if the slave computed successfully only a subinterval of the communication step - - `fmi2Error`: the communication step could not be carried out at all - - `fmi2Fatal`: if an error occurred which corrupted the FMU irreparably - - `fmi2Pending`: this status is returned if the slave executes the function asynchronously -- `enterEventMode::Array{fmi2Boolean, 1}`: Returns `enterEventMode[1]` to signal to the environment if the FMU shall call `fmi2EnterEventMode` -- `terminateSimulation::Array{fmi2Boolean, 1}`: Returns `terminateSimulation[1]` to signal if the simulation shall be terminated. -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations - -""" -function fmiCompletedIntegratorStep(str::fmi2Struct, args...; kwargs...) - fmi2CompletedIntegratorStep(str, args...; kwargs...) +function fmi3Unload(args...; kwargs...) + warnDeprecated("fmi3Unload", "unloadFMU", "FMI version is determined automatically.") + unloadFMU(args...; kwargs...) end -export fmiCompletedIntegratorStep - -""" -DEPRECATED - fmiGetDerivatives(str::fmi2Struct) +export fmi3Unload -Compute state derivatives at the current time instant and for the current states. - -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- `derivatives::Array{fmi2Real}`: Returns an array of `fmi2Real` values representing the `derivatives` for the current states. The ordering of the elements of the derivatives vector is identical to the ordering of the state -vector. -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations - -""" -DEPRECATED -function fmiGetDerivatives(str::fmi2Struct) - fmi2GetDerivatives(str) -end -export fmiGetDerivatives - -""" -DEPRECATED - fmiGetEventIndicators(str::fmi2Struct) - -Returns the event indicators of the FMU -# Arguments -- `str::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `str::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `str::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. - -# Returns -- `eventIndicators::Array{fmi2Real}`:The event indicators are returned as a vector represented by an array of "fmi2Real" values. -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations - -""" -function fmiGetEventIndicators(str::fmi2Struct) - fmi2GetEventIndicators(str) -end -export fmiGetEventIndicators - -""" -DEPRECATED - fmiGetContinuousStates(s::fmi2Struct) - -Return the new (continuous) state vector x -# Arguments -- `s::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `s::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `s::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -# Returns -- `x::Array{fmi2Real}`: Returns an array of `fmi2Real` values representing the new continuous state vector `x`. -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations - - -""" -function fmiGetContinuousStates(s::fmi2Struct) - fmi2GetContinuousStates(s) -end -export fmiGetContinuousStates - -""" -DEPRECATED - fmiGetNominalsOfContinuousStates(s::fmi2Struct) - -Return the new (continuous) state vector x - -# Arguments -- `s::fmi2Struct`: Representative for an FMU in the FMI 2.0.2 Standard. -More detailed: `fmi2Struct = Union{FMU2, FMU2Component}` - - `s::FMU2`: Mutable struct representing a FMU and all it instantiated instances in the FMI 2.0.2 Standard. - - `s::FMU2Component`: Mutable struct represents an instantiated instance of an FMU in the FMI 2.0.2 Standard. -# Returns -- `x::Array{fmi2Real}`: Returns an array of `fmi2Real` values representing the new continuous state vector `x`. -# Source -- FMISpec2.0.2 Link: [https://fmi-standard.org/](https://fmi-standard.org/) -- FMISpec2.0.2[p.16]: 2.1.2 Platform Dependent Definitions (fmi2TypesPlatform.h) -- FMISpec2.0.2[p.16]: 2.1.3 Status Returned by Functions -- FMISpec2.0.2[p.83]: 3.2.2 Evaluation of Model Equations - -""" -function fmiGetNominalsOfContinuousStates(s::fmi2Struct) - fmi2GetNominalsOfContinuousStates(s) -end -export fmiGetNominalsOfContinuousStates - -##### function setters - -function fmiSetFctGetTypesPlatform(fmu::FMU2, fun) - fmi2SetFctGetTypesPlatform(fmu, fun) +function fmiInfo(args...; kwargs...) + warnDeprecated("fmiInfo", "info") + info(args...; kwargs...) end +export fmi2Info -function fmiSetFctGetVersion(fmu::FMU2, fun) - fmi2SetFctGetVersion(fmu, fun) +function fmi2Info(args...; kwargs...) + warnDeprecated("fmi2Info", "info", "FMI version is determined automatically.") + info(args...; kwargs...) end +export fmi2Info -function fmiSetFctInstantiate(fmu::FMU2, fun) - fmi2SetFctInstantiate(fmu, fun) +function fmi3Info(args...; kwargs...) + warnDeprecated("fmi3Info", "info", "FMI version is determined automatically.") + info(args...; kwargs...) end - -function fmiSetFctFreeInstance(fmu::FMU2, fun) - fmi2SetFctFreeInstance(fmu, fun) -end - -function fmiSetFctSetDebugLogging(fmu::FMU2, fun) - fmi2SetFctSetDebugLogging(fmu, fun) -end - -function fmiSetFctSetupExperiment(fmu::FMU2, fun) - fmi2SetFctSetupExperiment(fmu, fun) -end - -function fmiSetEnterInitializationMode(fmu::FMU2, fun) - fmi2SetEnterInitializationMode(fmu, fun) -end - -function fmiSetFctExitInitializationMode(fmu::FMU2, fun) - fmi2SetFctExitInitializationMode(fmu, fun) -end - -function fmiSetFctTerminate(fmu::FMU2, fun) - fmi2SetFctTerminate(fmu, fun) -end - -function fmiSetFctReset(fmu::FMU2, fun) - fmi2SetFctReset(fmu, fun) -end - -function fmiSetFctGetReal(fmu::FMU2, fun) - fmi2SetFctGetReal(fmu, fun) -end - -function fmiSetFctGetInteger(fmu::FMU2, fun) - fmi2SetFctGetInteger(fmu, fun) -end - -function fmiSetFctGetBoolean(fmu::FMU2, fun) - fmi2SetFctGetBoolean(fmu, fun) -end - -function fmiSetFctGetString(fmu::FMU2, fun) - fmi2SetFctGetString(fmu, fun) -end - -function fmiSetFctSetReal(fmu::FMU2, fun) - fmi2SetFctSetReal(fmu, fun) -end - -function fmiSetFctSetInteger(fmu::FMU2, fun) - fmi2SetFctSetInteger(fmu, fun) -end - -function fmiSetFctSetBoolean(fmu::FMU2, fun) - fmi2SetFctSetBoolean(fmu, fun) -end - -function fmiSetFctSetString(fmu::FMU2, fun) - fmi2SetFctSetString(fmu, fun) -end - -function fmiSetFctSetTime(fmu::FMU2, fun) - fmi2SetFctSetTime(fmu, fun) -end - -function fmiSetFctSetContinuousStates(fmu::FMU2, fun) - fmi2SetFctSetContinuousStates(fmu, fun) -end - -function fmiSetFctEnterEventMode(fmu::FMU2, fun) - fmi2SetFctEnterEventMode(fmu, fun) -end - -function fmiSetFctNewDiscreteStates(fmu::FMU2, fun) - fmi2SetFctNewDiscreteStates(fmu, fun) -end - -function fmiSetFctEnterContinuousTimeMode(fmu::FMU2, fun) - fmi2SetFctEnterContinuousTimeMode(fmu, fun) -end - -function fmiSetFctCompletedIntegratorStep(fmu::FMU2, fun) - fmi2SetFctCompletedIntegratorStep(fmu, fun) -end - -function fmiSetFctGetDerivatives(fmu::FMU2, fun) - fmi2SetFctGetDerivatives(fmu, fun) -end - -function fmiSetFctGetEventIndicators(fmu::FMU2, fun) - fmi2SetFctGetEventIndicators(fmu, fun) -end - -function fmiSetFctGetContinuousStates(fmu::FMU2, fun) - fmi2SetFctGetContinuousStates(fmu, fun) -end - -function fmiSetFctGetNominalsOfContinuousStates(fmu::FMU2, fun) - fmi2SetFctGetNominalsOfContinuousStates(fmu, fun) -end - -function fmiGetSolutionTime(solution::FMU2Solution, args...; kwargs...) - fmi2GetSolutionTime(solution, args...; kwargs...) -end - -function fmiGetSolutionState(solution::FMU2Solution, args...; kwargs...) - fmi2GetSolutionState(solution, args...; kwargs...) -end - -function fmiGetSolutionDerivative(solution::FMU2Solution, args...; kwargs...) - fmi2GetSolutionDerivative(solution, args...; kwargs...) -end - -function fmiGetSolutionValue(solution::FMU2Solution, args...; kwargs...) - fmi2GetSolutionValue(solution, args...; kwargs...) -end - -# renames - -function fmiSampleDirectionalDerivative(args...; kwargs...) - fmi2SampleJacobian(args...; kwargs...) -end - -function fmiSampleDirectionalDerivative!(args...; kwargs...) - fmi2SampleJacobian!(args...; kwargs...) -end \ No newline at end of file +export fmi3Info \ No newline at end of file diff --git a/src/extensions/CSV.jl b/src/extensions/CSV.jl deleted file mode 100644 index eed60aea..00000000 --- a/src/extensions/CSV.jl +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMIImport: FMUSolution - -""" - fmiSaveSolutionCSV(solution::FMUSolution, filepath::AbstractString) - -Save a `solution` of an FMU simulation as csv file at `filepath`. -(requires Package CSV in Julia Environment) - -See also [`fmiSaveSolutionMAT`](@ref), [`fmiSaveSolutionJLD2`](@ref), [`fmiLoadSolutionJLD2`](@ref). -""" -function fmiSaveSolutionCSV(solution::FMUSolution, filepath::AbstractString) - df = DataFrames.DataFrame(time = solution.values.t) - for i in 1:length(solution.values.saveval[1]) - df[!, Symbol(fmi2ValueReferenceToString(solution.component.fmu, solution.valueReferences[i]))] = [val[i] for val in solution.values.saveval] - end - CSV.write(filepath, df) -end -export fmiSaveSolutionCSV diff --git a/src/extensions/JLD2.jl b/src/extensions/JLD2.jl deleted file mode 100644 index 660e0eba..00000000 --- a/src/extensions/JLD2.jl +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMIImport: FMUSolution - -""" - fmiSaveSolutionJLD2(solution::FMUSolution, filepath::AbstractString; keyword="solution") - -Save a `solution` of an FMU simulation under `keyword` in a jld2 file at `filepath`. -(requires Package JLD2 in Julia Environment) - -See also [`fmiSaveSolutionCSV`](@ref), [`fmiSaveSolutionMAT`](@ref), [`fmiLoadSolutionJLD2`](@ref). -""" -function fmiSaveSolutionJLD2(solution::FMUSolution, filepath::AbstractString; keyword="solution") - return JLD2.save(filepath, Dict(keyword=>solution)) -end -export fmiSaveSolutionJLD2 - -""" - fmiLoadSolutionJLD2(filepath::AbstractString; keyword="solution") - -Load a [`FMUSolution`](@ref) from jld2 file at `filepath` using `keyword` as jld2 keyword. -(requires Package JLD2 in Julia Environment) - -See also [`fmiSaveSolutionCSV`](@ref), [`fmiSaveSolutionMAT`](@ref), [`fmiSaveSolutionJLD2`](@ref). -""" -function fmiLoadSolutionJLD2(filepath::AbstractString; keyword="solution") - return JLD2.load(filepath, keyword) -end -export fmiLoadSolutionJLD2 \ No newline at end of file diff --git a/src/extensions/MAT.jl b/src/extensions/MAT.jl deleted file mode 100644 index ca79ce86..00000000 --- a/src/extensions/MAT.jl +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMIImport: FMUSolution - -""" - fmiSaveSolutionMAT(solution::FMUSolution, filepath::AbstractString) - - -Save a `solution` of an FMU simulation as mat file at `filepath`. -(requires Package MAT in Julia Environment) - -See also [`fmiSaveSolutionCSV`](@ref), [`fmiSaveSolutionJLD2`](@ref), [`fmiLoadSolutionJLD2`](@ref). -""" -function fmiSaveSolutionMAT(solution::FMUSolution, filepath::AbstractString) - file = MAT.matopen(filepath, "w") - x = collect.(solution.values.saveval) - v = [tup[k] for tup in x, k in 1:length(x[1])] - v = hcat(solution.values.t, v) - MAT.write(file, "time", v[:,1]) - for i in 2:length(v[1,:]) - MAT.write(file, replace(fmi2ValueReferenceToString(solution.component.fmu, solution.valueReferences[i-1])[1], "." => "_"), v[:,i]) - # df[!, Symbol(fmi2ValueReferenceToString(solution.component.fmu, solution.valueReferences[i]))] = [val[i] for val in solution.values.saveval] - end - - MAT.close(file) -end -export fmiSaveSolutionMAT \ No newline at end of file diff --git a/src/extensions/Plots.jl b/src/extensions/Plots.jl deleted file mode 100644 index 32aafb13..00000000 --- a/src/extensions/Plots.jl +++ /dev/null @@ -1,228 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMIImport: FMUSolution -import FMIImport.FMICore: unsense - -""" - fmiPlot(solution::FMUSolution; kwargs...) - -Create a figure and [`fmiPlot!`](@ref)'s the `solution` of a FMU simulation with the `kwargs` into it and returns the figure. -(requires Package Plots in Julia Environment) - -See also [`fmiPlot!`](@ref) -""" -function fmiPlot(solution::FMUSolution; kwargs...) - fig = Plots.plot(; xlabel="t [s]") - fmiPlot!(fig, solution; kwargs...) - return fig -end -export fmiPlot - -""" - fmiPlot!(fig::Plots.Plot, solution::FMUSolution; - [states::Union{Bool, Nothing}=nothing, - values::Union{Bool, Nothing}=nothing, - stateEvents::Union{Bool, Nothing}=nothing, - timeEvents::Union{Bool, Nothing}=nothing, - stateIndices=nothing, - valueIndices=nothing, - maxLabelLength=64, - plotkwargs...]) - -Plot the `solution` of a FMU simulation into `fig` and return the figure. - -# Arguments -- `fig::Plots.Plot`: Figure to plot into -- `solution::FMUSolution`: Struct containing information about the solutions values, success, states and events of a specific FMU simulation. -- `states::Union{Bool, Nothing}=nothing`: controls if states should be plotted (default = nothing: plot states from `solution`, as long as they exist) -- `values::Union{Bool, Nothing}=nothing`: controls if values should be plotted (default = nothing: plot values from `solution`, as long as they exist) -- `stateEvents::Union{Bool, Nothing}=nothing`: controls if stateEvents should be plotted (default = nothing: plot stateEvents from `solution`, if at least one and at most 100 exist) -- `timeEvents::Union{Bool, Nothing}=nothing`: controls if timeEvents should be plotted (default = nothing: plot timeEvents from `solution`, if at least one and at most 100 exist) -- `stateIndices=nothing`: controls which states will be plotted by index in state vector (default = nothing: plot all states) -- `valueIndices=nothing`: controls which values will be plotted by index (default = nothing: plot all values) -- `maxLabelLength=64`: controls the maximum length for legend labels (too long labels are cut from front) -- `plotkwargs...`: Arguments, that are passed on to Plots.plot! - -See also [`fmiPlot`](@ref) -""" -function fmiPlot!(fig::Plots.Plot, solution::FMUSolution; - states::Union{Bool, Nothing}=nothing, - values::Union{Bool, Nothing}=nothing, - stateEvents::Union{Bool, Nothing}=nothing, - timeEvents::Union{Bool, Nothing}=nothing, - stateIndices=nothing, - valueIndices=nothing, - maxLabelLength=64, - plotkwargs...) - - component = nothing - if isa(solution, FMU2Solution) - component = solution.component - elseif isa(solution, FMU3Solution) - component = solution.fmu.instances[end] # ToDo: This is very poor! - else - @assert false "Invalid solution type." - end - - numStateEvents = 0 - numTimeEvents = 0 - for e in solution.events - if e.indicator > 0 - numStateEvents += 1 - else - numTimeEvents += 1 - end - end - - if isnothing(states) - states = (solution.states !== nothing) - end - - if values === nothing - values = (solution.values !== nothing) - end - - if stateEvents === nothing - stateEvents = false - for e in solution.events - if e.indicator > 0 - stateEvents = true - break - end - end - - if numStateEvents > 100 - @info "fmiPlot(...): Number of state events ($(numStateEvents)) exceeding 100, disabling automatic plotting of state events (can be forced with keyword `stateEvents=true`)." - stateEvents = false - end - end - - if timeEvents === nothing - timeEvents = false - for e in solution.events - if e.indicator == 0 - timeEvents = true - break - end - end - - if numTimeEvents > 100 - @info "fmiPlot(...): Number of time events ($(numTimeEvents)) exceeding 100, disabling automatic plotting of time events (can be forced with keyword `timeEvents=true`)." - timeEvents = false - end - end - - if stateIndices === nothing - stateIndices = 1:length(component.fmu.modelDescription.stateValueReferences) - end - - if valueIndices === nothing - if solution.values !== nothing - valueIndices = 1:length(solution.values.saveval[1]) - end - end - - plot_min = Inf - plot_max = -Inf - - # plot states - if states - t = collect(unsense(e) for e in solution.states.t) - numValues = length(solution.states.u[1]) - - for v in 1:numValues - if v ∈ stateIndices - vr = component.fmu.modelDescription.stateValueReferences[v] - vrNames = fmi2ValueReferenceToString(component.fmu, vr) - vrName = length(vrNames) > 0 ? vrNames[1] : "?" - - vals = collect(unsense(data[v]) for data in solution.states.u) - - plot_min = min(plot_min, vals...) - plot_max = max(plot_max, vals...) - - # prevent legend labels from getting too long - label = "$vrName ($vr)" - labelLength = length(label) - if labelLength > maxLabelLength - label = "..." * label[labelLength-maxLabelLength:end] - end - - Plots.plot!(fig, t, vals; label=label, plotkwargs...) - end - end - end - - # plot recorded values - if values - t = collect(unsense(e) for e in solution.values.t) - numValues = length(solution.values.saveval[1]) - - for v in 1:numValues - if v ∈ valueIndices - vr = "[unknown]" - vrName = "[unknown]" - if solution.valueReferences != nothing && v <= length(solution.valueReferences) - vr = solution.valueReferences[v] - vrNames = fmi2ValueReferenceToString(component.fmu, vr) - vrName = length(vrNames) > 0 ? vrNames[1] : "?" - end - - vals = collect(unsense(data[v]) for data in solution.values.saveval) - - plot_min = min(plot_min, vals...) - plot_max = max(plot_max, vals...) - - # prevent legend labels from getting too long - label = "$vrName ($vr)" - labelLength = length(label) - if labelLength > maxLabelLength - label = "..." * label[labelLength-maxLabelLength:end] - end - - Plots.plot!(fig, t, vals; label=label, plotkwargs...) - end - end - end - - if stateEvents - first = true - for e in solution.events - if e.indicator > 0 - Plots.plot!(fig, [e.t, e.t], [plot_min, plot_max]; label=(first ? "State event(s)" : nothing), style=:dash, color=:blue) - first = false - end - end - end - - if timeEvents - first = true - for e in solution.events - if e.indicator == 0 - Plots.plot!(fig, [e.t, e.t], [plot_min, plot_max]; label=(first ? "Time event(s)" : nothing), style=:dash, color=:red) - first = false - end - end - end - - return fig -end -export fmiPlot! - -""" - Plots.plot(solution::FMUSolution; kwargs...) - Plots.plot!(fig::Plots.Plot, solution::FMUSolution; kwargs...) - -Plot FMUs using the original plot-command from Plots. - -See also [`fmiPlot`](@ref), [`fmiPlot!`](@ref). -""" Plots.plot, Plots.plot! -function Plots.plot(solution::FMUSolution; kwargs...) - fmiPlot(solution; kwargs...) -end -function Plots.plot!(fig::Plots.Plot, solution::FMUSolution; kwargs...) - fmiPlot!(fig, solution; kwargs...) -end diff --git a/src/sim.jl b/src/sim.jl new file mode 100644 index 00000000..b0a568f2 --- /dev/null +++ b/src/sim.jl @@ -0,0 +1,475 @@ +# +# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher +# Licensed under the MIT license. See LICENSE file in the project root for details. +# + +using FMIImport.FMIBase.SciMLBase: solve, RightRootFind, ReturnCode +using FMIImport.FMIBase.DiffEqCallbacks: CallbackSet, SavedValues, copyat_or_push! + +import LinearAlgebra: eigvals +import FMIImport.FMIBase.ProgressMeter + +import FMIImport: prepareSolveFMU, finishSolveFMU +import FMIImport.FMIBase: setupODEProblem, setupCallbacks, setupSolver!, eval! +import FMIImport.FMIBase: getEmptyReal, getEmptyValueReference, isTrue, isStatusOK +import FMIImport.FMIBase: doStep + +""" + simulate(fmu, instance=nothing, tspan=nothing; kwargs...) + simulate(fmu, tspan=nothing; kwargs...) + simulate(instance, tspan=nothing; kwargs...) + +Starts a simulation of the `FMU2` for the instantiated type: CS, ME or SE (this is selected automatically or during loading of the FMU). +You can force a specific simulation mode by calling [`simulateCS`](@ref), [`simulateME`](@ref) or [`simulateSE`](@ref) directly. + +# Arguments +- `fmu::FMU`: The FMU to be simulated. +- `c::Union{FMUInstance, Nothing}=nothing`: The instance (FMI3) or component (FMI2) of the FMU, `nothing` if not available. +- `tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing`: Simulation-time-span as tuple (default = nothing: use default value from FMU's model description or (0.0, 1.0) if not specified) + +# Keyword arguments +- `recordValues::fmi2ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` +- `saveat = nothing`: Time points to save (interpolated) values at (default = nothing: save at each solver timestep) +- `setup::Bool`: call fmi2SetupExperiment, fmi2EnterInitializationMode and fmi2ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `reset::Bool`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `instantiate::Bool`: call fmi2Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `freeInstance::Bool`: call fmi2FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `terminate::Bool`: call fmi2Terminate after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `inputValueReferences::fmi2ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each simulation step +- `inputFunction = nothing`: Function to get values for the input variables at each simulation step. +- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization +- `showProgress::Bool = true`: print simulation progressmeter in REPL + +## Input function pattern +[`c`: current component, `u`: current state ,`t`: current time, returning array of values to be passed to `fmi2SetReal(..., inputValueReferences, inputFunction(...))` or `fmi3SetFloat64`]: +- `inputFunction(t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, x::AbstractVector{<:Real}, u::AbstractVector{<:Real})` +- `inputFunction(x::AbstractVector{<:Real}, t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, x::AbstractVector{<:Real}, t::Real, u::AbstractVector{<:Real})` + +# Returns: +- A [`FMUSolution`](@ref) struct. + +See also [`simulate`](@ref), [`simulateME`](@ref), [`simulateCS`](@ref), [`simulateSE`](@ref). +""" +function simulate(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) + + if fmu.type == fmi2TypeCoSimulation + return simulateCS(fmu, c, tspan; kwargs...) + elseif fmu.type == fmi2TypeModelExchange + return simulateME(fmu, c, tspan; kwargs...) + else + error(unknownFMUType) + end +end +function simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) + + if fmu.type == fmi3TypeCoSimulation + return simulateCS(fmu, c, tspan; kwargs...) + elseif fmu.type == fmi3TypeModelExchange + return simulateME(fmu, c, tspan; kwargs...) + elseif fmu.type == fmi3TypeScheduledExecution + return simulateSE(fmu, c, tspan; kwargs...) + else + error(unknownFMUType) + end +end +simulate(c::FMUInstance, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulate(c.fmu, c, tspan; kwargs...) +simulate(fmu::FMU, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulate(fmu, nothing, tspan; kwargs...) +export simulate + +""" + simulateME(fmu, instance=nothing, tspan=nothing; kwargs...) + simulateME(fmu, tspan=nothing; kwargs...) + simulateME(instance, tspan=nothing; kwargs...) + +Simulate ME-FMU for the given simulation time interval. +State- and Time-Events are handled correctly. + +# Arguments +- `fmu::FMU`: The FMU to be simulated. +- `c::Union{FMUInstance, Nothing}=nothing`: The instance (FMI3) or component (FMI2) of the FMU, `nothing` if not available. +- `tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing`: Simulation-time-span as tuple (default = nothing: use default value from FMU's model description or (0.0, 1.0) if not specified) + +# Keyword arguments +- `solver = nothing`: Any Julia-supported ODE-solver (default = nothing: use DifferentialEquations.jl default solver) +- `recordValues::fmi2ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` +- `recordEventIndicators::Union{AbstractArray{<:Integer, 1}, UnitRange{<:Integer}, Nothing} = nothing`: Array or Range of event indicators to record +- `recordEigenvalues::Bool=false`: compute and record eigenvalues +- `saveat = nothing`: Time points to save (interpolated) values at (default = nothing: save at each solver timestep) +- `x0::Union{AbstractArray{<:Real}, Nothing} = nothing`: inital fmu State (default = nothing: use current or default-inital fmu state) +- `setup::Bool`: call fmi2SetupExperiment, fmi2EnterInitializationMode and fmi2ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `reset::Bool`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `instantiate::Bool`: call fmi2Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `freeInstance::Bool`: call fmi2FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `terminate::Bool`: call fmi2Terminate after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `inputValueReferences::fmi2ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each simulation step +- `inputFunction = nothing`: Function to get values for the input variables at each simulation step. +- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization +- `callbacksBefore = []`: callbacks to call *before* the internal callbacks for state- and time-events are called +- `callbacksAfter = []`: callbacks to call *after* the internal callbacks for state- and time-events are called +- `showProgress::Bool = true`: print simulation progressmeter in REPL +- `solveKwargs...`: keyword arguments that get passed onto the solvers solve call + +## Input function pattern +[`c`: current component, `u`: current state ,`t`: current time, returning array of values to be passed to `fmi2SetReal(..., inputValueReferences, inputFunction(...))` or `fmi3SetFloat64`]: +- `inputFunction(t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, x::AbstractVector{<:Real}, u::AbstractVector{<:Real})` +- `inputFunction(x::AbstractVector{<:Real}, t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, x::AbstractVector{<:Real}, t::Real, u::AbstractVector{<:Real})` + +# Returns: +- A [`FMUSolution`](@ref) struct. + +See also [`simulate`](@ref), [`simulateCS`](@ref), [`simulateSE`](@ref). +""" +function simulateME(fmu::FMU, c::Union{FMUInstance, Nothing}, tspan::Tuple{Real, Real}; + solver = nothing, # [ToDo] type + recordValues::fmi2ValueReferenceFormat = nothing, + recordEventIndicators::Union{AbstractArray{<:Integer, 1}, UnitRange{<:Integer}, Nothing} = nothing, + recordEigenvalues::Bool=false, + saveat = nothing, # [ToDo] type + x0::Union{AbstractArray{<:Real}, Nothing} = nothing, + setup::Bool=fmu.executionConfig.setup, + reset::Bool=fmu.executionConfig.reset, + instantiate::Bool=fmu.executionConfig.instantiate, + freeInstance::Bool=fmu.executionConfig.freeInstance, + terminate::Bool=fmu.executionConfig.terminate, + inputValueReferences::fmi2ValueReferenceFormat = nothing, + inputFunction = nothing, + parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, + callbacksBefore::AbstractVector=[], # [ToDo] type + callbacksAfter::AbstractVector=[], # [ToDo] type + showProgress::Bool = true, + solveKwargs...) + + @assert isModelExchange(fmu) "simulateME(...): This function supports Model Excahnge FMUs only." + + recordValues = prepareValueReference(fmu, recordValues) + inputValueReferences = prepareValueReference(fmu, inputValueReferences) + hasInputs = length(inputValueReferences) > 0 + + solveKwargs = Dict{Symbol, Any}(solveKwargs...) + tspan = setupSolver!(fmu, tspan, solveKwargs) + t_start, t_stop = tspan + + if !isnothing(saveat) + solveKwargs[:saveat] = saveat + end + + progressMeter = nothing + if showProgress + progressMeter = ProgressMeter.Progress(1000; desc="Simulating ME-FMU ...", color=:blue, dt=1.0) #, barglyphs=ProgressMeter.BarGlyphs("[=> ]")) + ProgressMeter.update!(progressMeter, 0) # show it! + end + + # input function handling + _inputFunction = nothing + if !isnothing(inputFunction) + _inputFunction = FMUInputFunction(inputFunction, inputValueReferences) + end + + inputs = nothing + if hasInputs + inputValues = eval!(_inputFunction, nothing, nothing, t_start) + inputs = Dict(inputValueReferences .=> inputValues) + end + c, x0 = prepareSolveFMU(fmu, c, :ME; + parameters=parameters, t_start=t_start, t_stop=t_stop, x0=x0, inputs=inputs) + + # Zero state FMU: add dummy state + if c.fmu.isZeroState + x0 = [0.0] + end + + @assert !isnothing(x0) "x0 is nothing after prepare!" + + c.problem = setupODEProblem(c, x0, tspan; inputFunction=_inputFunction) + cbs = setupCallbacks(c, recordValues, recordEventIndicators, recordEigenvalues, _inputFunction, inputValueReferences, progressMeter, t_start, t_stop, saveat) + + #solveKwargs = Dict(solveKwargs...) + #setupSolver(fmu, solveKwargs) + + for cb in callbacksBefore + insertAt!(cbs, cb, 1) + end + + for cb in callbacksAfter + push!(cbs, cb) + end + + # from here on, we are in event mode, if `setup=false` this is the job of the user + #@assert c.state == fmi2ComponentStateEventMode "FMU needs to be in event mode after setup." + + # if x0 === nothing + # x0 = fmi2GetContinuousStates(c) + # x0_nom = fmi2GetNominalsOfContinuousStates(c) + # end + + # initial event handling + #handleEvents(c) + #fmi2EnterContinuousTimeMode(c) + + # callback functions + + if isnothing(solver) + c.solution.states = solve(c.problem; callback = CallbackSet(cbs...), solveKwargs...) + else + c.solution.states = solve(c.problem, solver; callback = CallbackSet(cbs...), solveKwargs...) + end + + c.solution.success = (c.solution.states.retcode == ReturnCode.Success) + + if !c.solution.success + logWarning(fmu, "FMU simulation failed with solver return code `$(c.solution.states.retcode)`, please check log for hints.") + end + + # ZeroStateFMU: remove dummy state + if c.fmu.isZeroState + c.solution.states = nothing + end + + # cleanup progress meter + if showProgress + ProgressMeter.finish!(progressMeter) + end + + finishSolveFMU(fmu, c; freeInstance=freeInstance, terminate=terminate) + + return c.solution +end +simulateME(c::FMUInstance, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulateME(c.fmu, c, tspan; kwargs...) +simulateME(fmu::FMU, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulateME(fmu, nothing, tspan; kwargs...) +export simulateME + +############ Co-Simulation ############ + +""" + simulateCS(fmu, instance=nothing, tspan=nothing; kwargs...) + simulateCS(fmu, tspan=nothing; kwargs...) + simulateCS(instance, tspan=nothing; kwargs...) + +Simulate CS-FMU for the given simulation time interval. +State- and Time-Events are handled internally by the FMU. + +# Arguments +- `fmu::FMU`: The FMU to be simulated. +- `c::Union{FMUInstance, Nothing}=nothing`: The instance (FMI3) or component (FMI2) of the FMU, `nothing` if not available. +- `tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing`: Simulation-time-span as tuple (default = nothing: use default value from FMU's model description or (0.0, 1.0) if not specified) + +# Keyword arguments +- `tolerance::Union{Real, Nothing} = nothing`: The tolerance for the internal FMU solver. +- `recordValues::fmi2ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` +- `saveat = nothing`: Time points to save (interpolated) values at (default = nothing: save at each solver timestep) +- `setup::Bool`: call fmi2SetupExperiment, fmi2EnterInitializationMode and fmi2ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `reset::Bool`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `instantiate::Bool`: call fmi2Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `freeInstance::Bool`: call fmi2FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `terminate::Bool`: call fmi2Terminate after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) +- `inputValueReferences::fmi2ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each simulation step +- `inputFunction = nothing`: Function to get values for the input variables at each simulation step. +- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Real, Integer, Boolean, String) to set parameters during initialization +- `showProgress::Bool = true`: print simulation progressmeter in REPL + +## Input function pattern +[`c`: current component, `u`: current state ,`t`: current time, returning array of values to be passed to `fmi2SetReal(..., inputValueReferences, inputFunction(...))` or `fmi3SetFloat64`]: +- `inputFunction(t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, x::AbstractVector{<:Real}, u::AbstractVector{<:Real})` +- `inputFunction(x::AbstractVector{<:Real}, t::Real, u::AbstractVector{<:Real})` +- `inputFunction(c::Union{FMUInstance, Nothing}, x::AbstractVector{<:Real}, t::Real, u::AbstractVector{<:Real})` + +# Returns: +- A [`FMUSolution`](@ref) struct. + +See also [`simulate`](@ref), [`simulateME`](@ref), [`simulateSE`](@ref). +""" +function simulateCS(fmu::FMU, c::Union{FMUInstance, Nothing}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; + tolerance::Union{Real, Nothing} = nothing, + dt::Union{Real, Nothing} = nothing, + recordValues::fmi2ValueReferenceFormat = nothing, + saveat = [], + setup::Bool=fmu.executionConfig.setup, + reset::Bool=fmu.executionConfig.reset, + instantiate::Bool=fmu.executionConfig.instantiate, + freeInstance::Bool=fmu.executionConfig.freeInstance, + terminate::Bool=fmu.executionConfig.terminate, + inputValueReferences::fmiValueReferenceFormat = nothing, + inputFunction = nothing, + showProgress::Bool=true, + parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing) + + @assert isCoSimulation(fmu) "simulateCS(...): This function supports Co-Simulation FMUs only." + + # input function handling + @debug "Simulating CS-FMU: Preparing input function ..." + inputValueReferences = prepareValueReference(fmu, inputValueReferences) + hasInputs = (length(inputValueReferences) > 0) + + _inputFunction = nothing + u = getEmptyReal(fmu) + u_refs = getEmptyValueReference(fmu) + if hasInputs + _inputFunction = FMUInputFunction(inputFunction, inputValueReferences) + u_refs = _inputFunction.vrs + end + + # outputs + @debug "Simulating CS-FMU: Preparing outputs ..." + y_refs = getEmptyValueReference(fmu) + y = getEmptyReal(fmu) + if !isnothing(recordValues) + y_refs = prepareValueReference(fmu, recordValues) + y = zeros(fmi2Real, length(y_refs)) + end + + t_start, t_stop = (tspan == nothing ? (nothing, nothing) : tspan) + + # pull default values from the model description - if not given by user + @debug "Simulating CS-FMU: Pulling default values ..." + variableSteps = isCoSimulation(fmu) && isTrue(fmu.modelDescription.coSimulation.canHandleVariableCommunicationStepSize) + + t_start = t_start === nothing ? getDefaultStartTime(fmu.modelDescription) : t_start + t_start = t_start === nothing ? 0.0 : t_start + + t_stop = t_stop === nothing ? getDefaultStopTime(fmu.modelDescription) : t_stop + t_stop = t_stop === nothing ? 1.0 : t_stop + + tolerance = tolerance === nothing ? getDefaultTolerance(fmu.modelDescription) : tolerance + tolerance = tolerance === nothing ? 0.0 : tolerance + + dt = dt === nothing ? getDefaultStepSize(fmu.modelDescription) : dt + dt = dt === nothing ? 1e-3 : dt + + @debug "Simulating CS-FMU: Preparing inputs ..." + inputs = nothing + if hasInputs + inputValues = eval!(_inputFunction, nothing, nothing, t_start) + inputs = Dict(inputValueReferences .=> inputValues) + end + + @debug "Simulating CS-FMU: Preparing solve ..." + c, _ = prepareSolveFMU(fmu, c, :CS; + instantiate=instantiate, freeInstance=freeInstance, terminate=terminate, reset=reset, setup=setup, parameters=parameters, + t_start=t_start, t_stop=t_stop, tolerance=tolerance, inputs=inputs) + fmusol = c.solution + + # default setup + if length(saveat) == 0 + saveat = t_start:dt:t_stop + end + + # setup if no variable steps + if variableSteps == false + if length(saveat) >= 2 + dt = saveat[2] - saveat[1] + end + end + + t = t_start + + progressMeter = nothing + if showProgress + progressMeter = ProgressMeter.Progress(1000; desc="Sim. CS-FMU ...", color=:blue, dt=1.0) + ProgressMeter.update!(progressMeter, 0) # show it! + end + + first_step = true + + fmusol.values = SavedValues(Float64, Tuple{collect(Float64 for i in 1:length(y_refs))...} ) + fmusol.valueReferences = copy(y_refs) + + i = 1 + + fmusol.success = true + + @debug "Starting simulation from $(t_start) to $(t_stop), variable steps: $(variableSteps)" + + while t < t_stop + + if variableSteps + if length(saveat) > (i+1) + dt = saveat[i+1] - saveat[i] + else + dt = t_stop - t + end + end + + if !first_step + ret = doStep(c, dt; currentCommunicationPoint=t) + + if !isStatusOK(fmu, ret) + fmusol.success = false + end + + t = t + dt + i += 1 + else + first_step = false + end + + if hasInputs + u = eval!(_inputFunction, c, nothing, t) + end + + c(u=u, u_refs=u_refs, y=y, y_refs=y_refs) + + svalues = (y...,) + copyat_or_push!(fmusol.values.t, i, t) + copyat_or_push!(fmusol.values.saveval, i, svalues, Val{false}) + + if !isnothing(progressMeter) + ProgressMeter.update!(progressMeter, floor(Integer, 1000.0*(t-t_start)/(t_stop-t_start)) ) + end + + end + + if !fmusol.success + logWarning(fmu, "FMU simulation failed, please check log for hints.") + end + + if !isnothing(progressMeter) + ProgressMeter.finish!(progressMeter) + end + + finishSolveFMU(fmu, c; freeInstance=freeInstance, terminate=terminate) + + return fmusol +end +simulateCS(c::FMUInstance, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulateCS(c.fmu, c, tspan; kwargs...) +simulateCS(fmu::FMU, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulateCS(fmu, nothing, tspan; kwargs...) +export simulateCS + +# [TODO] simulate ScheduledExecution +""" + simulateSE(fmu, instance=nothing, tspan=nothing; kwargs...) + simulateSE(fmu, tspan=nothing; kwargs...) + simulateSE(instance, tspan=nothing; kwargs...) + +To be implemented ... + +# Arguments +- `fmu::FMU3`: The FMU to be simulated. Note: SE is only available in FMI3. +- `c::Union{FMU3Instance, Nothing}=nothing`: The instance (FMI3) of the FMU, `nothing` if not available. +- `tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing`: Simulation-time-span as tuple (default = nothing: use default value from FMU's model description or (0.0, 1.0) if not specified) + +# Keyword arguments +- To be implemented ... + +# Returns: +- A [`FMUSolution`](@ref) struct. + +See also [`simulate`](@ref), [`simulateME`](@ref), [`simulateCS`](@ref). +""" +function simulateSE(fmu::FMU2, c::Union{FMU2Component, Nothing}) + @assert false "This is a FMI2-FMU, scheduled execution is not supported in FMI2." +end +function simulateSE(fmu::FMU3, c::Union{FMU3Instance, Nothing}) + # [ToDo] + @assert false "Not implemented yet. Please open an issue if this is needed." +end +simulateSE(c::FMUInstance, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulateSE(c.fmu, c, tspan; kwargs...) +simulateSE(fmu::FMU, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulateSE(fmu, nothing, tspan; kwargs...) +export simulateSE \ No newline at end of file diff --git a/test/FMI2/cs_me.jl b/test/FMI2/cs_me.jl deleted file mode 100644 index 2e0de3cd..00000000 --- a/test/FMI2/cs_me.jl +++ /dev/null @@ -1,33 +0,0 @@ -############### -# Prepare FMU # -############### - -t_start = 0.0 -t_stop = 1.0 - -### - -fmuStruct, myFMU = getFMUStruct("SpringPendulum1D") - -sol = fmiSimulateCS(fmuStruct, (t_start, t_stop)) -@test sol.success -sol = fmiSimulateME(fmuStruct, (t_start, t_stop); solver=FBDF(autodiff=false)) -@test sol.success - -fmiUnload(myFMU) - -### - -fmuStruct, myFMU = getFMUStruct("SpringPendulum1D"; type=:ME) - -sol = fmiSimulate(fmuStruct, (t_start, t_stop); solver=FBDF(autodiff=false)) -@test sol.success -fmiUnload(myFMU) - -### - -fmuStruct, myFMU = getFMUStruct("SpringPendulum1D"; type=:CS) - -sol = fmiSimulate(fmuStruct, (t_start, t_stop)) -@test sol.success -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI2/exec_config.jl b/test/FMI2/exec_config.jl deleted file mode 100644 index 47921a2b..00000000 --- a/test/FMI2/exec_config.jl +++ /dev/null @@ -1,71 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMI.FMIImport - -t_start = 0.0 -t_stop = 1.0 - -fmuStruct = Dict{Symbol, Union{FMU2, FMU2Component}}() -myFMU = Dict{Symbol, FMU2}() - -fmuStruct[:ME], myFMU[:ME] = getFMUStruct("SpringPendulum1D"; type=:ME) -fmuStruct[:CS], myFMU[:CS] = getFMUStruct("SpringPendulum1D"; type=:CS) - -for execConf in (FMU2_EXECUTION_CONFIGURATION_NO_FREEING, FMU2_EXECUTION_CONFIGURATION_RESET, FMU2_EXECUTION_CONFIGURATION_NO_RESET) # ToDo: Add `FMU2_EXECUTION_CONFIGURATION_NOTHING` - for mode in (:CS, :ME) - global fmuStruct, myFMU - - @info "\t$(mode) | $(execConf)" - - myFMU[mode].executionConfig = execConf - - # sim test - numInst = length(myFMU[mode].components) - - if mode == :CS - fmiSimulateCS(fmuStruct[mode], (t_start, t_stop)) - elseif mode == :ME - fmiSimulateME(fmuStruct[mode], (t_start, t_stop)) - else - @assert false "Unknown mode `$(mode)`." - end - - if execConf.instantiate - numInst += 1 - end - if execConf.freeInstance - numInst -= 1 - end - - @test length(myFMU[mode].components) == numInst - - othermode = (mode == :CS ? :ME : :CS) - - # prepare next run start - if isa(fmuStruct[mode], FMU2) - if !execConf.freeInstance - fmi2FreeInstance!(myFMU[mode]) - end - - fmi2Instantiate!(myFMU[othermode]; type=(othermode==:ME ? fmi2TypeModelExchange : fmi2TypeCoSimulation)) - - elseif isa(fmuStruct[mode], FMU2Component) - if !execConf.freeInstance - fmi2FreeInstance!(fmuStruct[mode]) - end - fmuStruct[othermode] = fmi2Instantiate!(myFMU[othermode]; type=(othermode==:ME ? fmi2TypeModelExchange : fmi2TypeCoSimulation)) - - else - @assert false "Unknown fmuStruct type `$(typeof(fmuStruct[mode]))`" - end - - # prepare next run end - - end -end - -fmiUnload(myFMU[:ME]) -fmiUnload(myFMU[:CS]) \ No newline at end of file diff --git a/test/FMI2/getter_setter.jl b/test/FMI2/getter_setter.jl deleted file mode 100644 index a5a08bd1..00000000 --- a/test/FMI2/getter_setter.jl +++ /dev/null @@ -1,85 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -############### -# Prepare FMU # -############### - -fmuStruct, myFMU = getFMUStruct("IO"; type=:CS) - -if isa(fmuStruct, FMU2) - # [Note] no instance allocated at this point - fmi2Instantiate!(fmuStruct) -end - -@test fmiSetupExperiment(fmuStruct, 0.0) == 0 - -@test fmiEnterInitializationMode(fmuStruct) == 0 - -realValueReferences = ["p_real", "u_real"] -integerValueReferences = ["p_integer", "u_integer"] -booleanValueReferences = ["p_boolean", "u_boolean"] -stringValueReferences = ["p_string", "p_string"] - -######################### -# Testing Single Values # -######################### - -rndReal = 100 * rand() -rndInteger = round(Integer, 100 * rand()) -rndBoolean = rand() > 0.5 -rndString = Random.randstring(12) - -cacheReal = 0.0 -cacheInteger = 0 -cacheBoolean = false -cacheString = "" - -fmiSet(fmuStruct, - [realValueReferences[1], integerValueReferences[1], booleanValueReferences[1], stringValueReferences[1]], - [rndReal, rndInteger, rndBoolean, rndString]) -@test fmiGet(fmuStruct, - [realValueReferences[1], integerValueReferences[1], booleanValueReferences[1], stringValueReferences[1]]) == - [rndReal, rndInteger, rndBoolean, rndString] - -#@test fmiGetStartValue(fmuStruct, "p_enumeration") == "myEnumeration1" -@test fmiGetStartValue(fmuStruct, "p_string") == "Hello World!" -@test fmiGetStartValue(fmuStruct, "p_real") == 0.0 - -################## -# Testing Arrays # -################## - -rndReal = [100 * rand(), 100 * rand()] -rndInteger = [round(Integer, 100 * rand()), round(Integer, 100 * rand())] -rndBoolean = [(rand() > 0.5), (rand() > 0.5)] -tmp = Random.randstring(8) -rndString = [tmp, tmp] - -cacheReal = [0.0, 0.0] -cacheInteger = [FMI.fmi2Integer(0), FMI.fmi2Integer(0)] -cacheBoolean = [FMI.fmi2Boolean(false), FMI.fmi2Boolean(false)] -cacheString = [pointer(""), pointer("")] - -#@test fmiGetStartValue(fmuStruct, ["p_enumeration", "p_string", "p_real"]) == ["myEnumeration1", "Hello World!", 0.0] -@test fmiGetStartValue(fmuStruct, ["p_string", "p_real"]) == ["Hello World!", 0.0] - -#################################### -# Testing input/output derivatives # -#################################### - -@test fmiSetRealInputDerivatives(fmuStruct, ["u_real"], ones(FMI.fmi2Integer, 1), zeros(1)) == 0 - -@test fmiExitInitializationMode(fmuStruct) == 0 -@test fmiDoStep(fmuStruct, 0.1) == 0 - -dirs = fmiGetRealOutputDerivatives(fmuStruct, ["y_real"], ones(FMI.fmi2Integer, 1)) -@test dirs == 0.0 # ToDo: Force a `dirs != 0.0` - -############ -# Clean up # -############ - -fmiUnload(myFMU) diff --git a/test/FMI2/load_save.jl b/test/FMI2/load_save.jl deleted file mode 100644 index 5c15b332..00000000 --- a/test/FMI2/load_save.jl +++ /dev/null @@ -1,91 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using JLD2 -using CSV -using DataFrames -using MAT - -# our simulation setup -t_start = 0.0 -t_stop = 8.0 - -# load the FMU container -fmuStruct, myFMU = getFMUStruct("SpringFrictionPendulum1D") - -recordValues = ["mass.s", "mass.v"] -solutionME = fmiSimulateME(myFMU, (t_start, t_stop); recordValues=recordValues, solver=FBDF(autodiff=false)) -solutionCS = fmiSimulateCS(myFMU, (t_start, t_stop); recordValues=recordValues) - -# ME - -fmiSaveSolution(solutionME, "solutionME.jld2") - -#@warn "Loading solution tests are disabled for now." -#anotherSolutionME = solutionME -anotherSolutionME = fmiLoadSolution("solutionME.jld2") - -@test solutionME.success == true -@test solutionME.success == anotherSolutionME.success -@test solutionME.states.u == anotherSolutionME.states.u -@test solutionME.states.t == anotherSolutionME.states.t -@test solutionME.values.saveval == anotherSolutionME.values.saveval -@test solutionME.values.t == anotherSolutionME.values.t - -# ME-BONUS: events -@test solutionME.events == anotherSolutionME.events - -# test csv -x = collect.(solutionME.values.saveval) -v = [tup[k] for tup in x, k in 1:length(x[1])] -fmiSaveSolutionCSV(solutionME, "solutionME.csv") -csv_df = CSV.read("solutionME.csv", DataFrame) - -@test v[:,1] == csv_df[!, 2] -@test solutionME.values.t == csv_df[!, 1] - -# test mat -fmiSaveSolutionMAT(solutionME, "solutionME.mat") -vars = matread("solutionME.mat") -@test vars["time"] == solutionME.values.t -for i in 1:length(solutionME.valueReferences) - key = replace(fmi2ValueReferenceToString(solutionME.component.fmu, solutionME.valueReferences[i])[1], "." => "_") - @test vars[key] == v[:,i] -end - -# CS - -fmiSaveSolution(solutionCS, "solutionCS.jld2") - -#@warn "Loading solution tests are disabled for now." -#anotherSolutionCS = solutionCS -anotherSolutionCS = fmiLoadSolution("solutionCS.jld2") - -@test solutionCS.success == true -@test solutionCS.success == anotherSolutionCS.success -@test solutionCS.values.saveval == anotherSolutionCS.values.saveval -@test solutionCS.values.t == anotherSolutionCS.values.t - -# test csv -x = collect.(solutionCS.values.saveval) -v = [tup[k] for tup in x, k in 1:length(x[1])] -fmiSaveSolutionCSV(solutionCS, "solutionCS.csv") -csv_df = CSV.read("solutionCS.csv", DataFrame) - -@test v[:,1] == csv_df[!, 2] -@test solutionCS.values.t == csv_df[!, 1] - - -# test mat -fmiSaveSolutionMAT(solutionCS, "solutionME.mat") -vars = matread("solutionME.mat") -@test vars["time"] == solutionCS.values.t -for i in 1:length(solutionCS.valueReferences) - key = replace(fmi2ValueReferenceToString(solutionCS.component.fmu, solutionCS.valueReferences[i])[1], "." => "_") - @test vars[key] == v[:,i] -end - -# unload the FMU, remove unpacked data on disc ("clean up") -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI2/performance.jl b/test/FMI2/performance.jl deleted file mode 100644 index 66fb138e..00000000 --- a/test/FMI2/performance.jl +++ /dev/null @@ -1,228 +0,0 @@ -# -# Copyright (c) 2023 Tobias Thummerer, Lars Mikelsons -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -# this is temporary until it's implemented in native Julia, see: -# https://discourse.julialang.org/t/debug-has-massive-performance-impact/103974/19 -using Logging -if Sys.iswindows() - Logging.disable_logging(Logging.Debug) -end - -using FMI, FMI.FMIImport, FMI.FMIImport.FMICore, FMIZoo -using BenchmarkTools, Test - -fmuStruct, myFMU = getFMUStruct("BouncingBall1D", "Dymola", "2022x"; type=:ME) - -c = fmi2Instantiate!(fmu) - -evalBenchmark = function(b) - res = run(b) - min_time = min(res.times...) - memory = res.memory - allocs = res.allocs - return min_time, memory, allocs -end - -########## enter / exit initialization mode ########## - -function enterExitInitializationModeReset(c) - fmi2Reset(c) - fmi2EnterInitializationMode(c) - fmi2ExitInitializationMode(c) - return nothing -end - -b = @benchmarkable enterExitInitializationModeReset($c) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 0 -@test memory <= 0 - -########## string-value-reference conversion ########## - -buffer = zeros(fmi2Real, 2) -vrs_str = ["mass_radius", "der(mass_v)"] -vrs = prepareValueReference(fmu, vrs_str) - -function stringToValueReference(md, name) - fmi2StringToValueReference(md, name) - return nothing -end - -b = @benchmarkable stringToValueReference($fmu.modelDescription, $vrs_str[1]) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 0 -@test memory <= 0 - -b = @benchmarkable stringToValueReference($fmu.modelDescription, $vrs_str) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 1 # allocation of one tuple, containing the model description -@test memory <= 64 - -########## get real ########## - -vrs = prepareValueReference(fmu, vrs_str) - -function getReal!(c, vrs, buffer) - fmi2GetReal!(c, vrs, buffer) - return nothing -end -function getReal(c, vrs) - fmi2GetReal(c, vrs) - return nothing -end - -b = @benchmarkable getReal!($c, $vrs, $buffer) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 0 -@test memory <= 0 - -b = @benchmarkable getReal!($c, $vrs_str, $buffer) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 1 # allocation for on-the-fly string conversion -@test memory <= 64 - -b = @benchmarkable getReal($c, $vrs_str) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 2 # allocation for on-the-fly string conversion AND allocating an array for the results -@test memory <= 144 - -########## get derivatives ########## - -buffer = zeros(fmi2Real, 2) -nx = Csize_t(length(buffer)) - -function getDerivatives!(c, buffer, nx) - fmi2GetDerivatives!(c, buffer, nx) - return nothing -end - -function getDerivatives!(c, buffer) - fmi2GetDerivatives!(c, buffer) - return nothing -end - -function getDerivatives(c) - fmi2GetDerivatives(c) - return nothing -end - -b = @benchmarkable getDerivatives!($c, $buffer, $nx) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 0 -@test memory <= 0 - -b = @benchmarkable getDerivatives!($c, $buffer) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 0 -@test memory <= 0 - -b = @benchmarkable getDerivatives($c) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 1 # this is the allocation for the 1 result array -@test memory <= 80 # this is memory for 2 array elements and the array pointer (+1) - -########## f(x) evaluation / right-hand side ########## - -c.solution = FMU2Solution(c) -fmi2Reset(c) -fmi2EnterInitializationMode(c) -fmi2ExitInitializationMode(c) - -import FMI.FMIImport.FMICore: eval! - -cRef = UInt64(pointer_from_objref(c)) -dx = zeros(fmi2Real, 2) -dx_refs = c.fmu.modelDescription.derivativeValueReferences -y = zeros(fmi2Real, 0) -y_refs = zeros(fmi2ValueReference, 0) -x = zeros(fmi2Real, 2) -u = zeros(fmi2Real, 0) -u_refs = zeros(fmi2ValueReference, 0) -p = zeros(fmi2Real, 0) -p_refs = zeros(fmi2ValueReference, 0) -ec = zeros(fmi2Real, 0) -ec_idcs = zeros(fmi2ValueReference, 0) -t = -1.0 -b = @benchmarkable eval!($cRef, $dx, $dx_refs, $y, $y_refs, $x, $u, $u_refs, $p, $p_refs, $ec, $ec_idcs, $t) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 0 -@test memory <= 0 - -b = @benchmarkable $c(dx=$dx, y=$y, y_refs=$y_refs, x=$x, u=$u, u_refs=$u_refs, p=$p, p_refs=$p_refs, ec=$ec, ec_idcs=$ec_idcs, t=$t) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 9 # [ToDo] 3 `ignore_derivatives` causes an extra 3 allocations (48 bytes) -@test memory <= 224 # [ToDo] reduce again 48 - -_p = () -b = @benchmarkable FMI.fx($c, $dx, $x, $_p, $t, nothing) -min_time, memory, allocs = evalBenchmark(b) -# ToDo: This is too much, but currently necessary to be compatible with all AD-frameworks, as well as ForwardDiffChainRules -@test allocs <= 9 # [ToDo]3 -@test memory <= 224 # [ToDo] reduce again 48 - -# AD - -using FMISensitivity -import FMISensitivity.ChainRulesCore -import FMISensitivity.ChainRulesCore: ZeroTangent, NoTangent -import FMISensitivity.ForwardDiff -import FMISensitivity.ReverseDiff - -# frule -Ξ”x = similar(x) -Ξ”tuple = (NoTangent(), NoTangent(), NoTangent(), NoTangent(), NoTangent(), NoTangent(), Ξ”x, NoTangent(), NoTangent(), NoTangent(), NoTangent(), NoTangent(), NoTangent(), NoTangent()) -fun = function(_x) - Ξ©, βˆ‚Ξ© = ChainRulesCore.frule(Ξ”tuple, eval!, cRef, dx, dx_refs, y, y_refs, _x, u, u_refs, p, p_refs, ec, ec_idcs, t) -end - -b = @benchmarkable fun($x) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 4 -@test memory <= 144 - -# rrule -fun = function (_x) - Ξ©, pullback = ChainRulesCore.rrule(eval!, cRef, dx, dx_refs, y, y_refs, _x, u, u_refs, p, p_refs, ec, ec_idcs, t) -end - -b = @benchmarkable fun($x) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 9 -@test memory <= 400 - -# rrule pullback -Ξ©, pullback = ChainRulesCore.rrule(eval!, cRef, dx, dx_refs, y, y_refs, x, u, u_refs, p, p_refs, ec, ec_idcs, t) -rΜ„ = copy(dx) -fun = function(_rΜ„, _pullback) - _pullback(_rΜ„) -end - -b = @benchmarkable fun($rΜ„, $pullback) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 5 -@test memory <= 144 - -# eval! -fun = function(_x) - eval!(cRef, dx, dx_refs, y, y_refs, _x, u, u_refs, p, p_refs, ec, ec_idcs, t) -end - -b = @benchmarkable fun($x) -min_time, memory, allocs = evalBenchmark(b) -@test allocs <= 0 -@test memory <= 0 - -config = ForwardDiff.JacobianConfig(fun, x, ForwardDiff.Chunk{length(x)}()) -b = @benchmarkable ForwardDiff.jacobian($fun, $x, $config) -min_time, memory, allocs = evalBenchmark(b) -# ToDo: This is way too much! -@test allocs <= 240 -@test memory <= 13000 - -b = @benchmarkable ReverseDiff.jacobian($fun, $x) -min_time, memory, allocs = evalBenchmark(b) -# ToDo: This is way too much! -@test allocs <= 240 -@test memory <= 12000 \ No newline at end of file diff --git a/test/FMI2/plots.jl b/test/FMI2/plots.jl deleted file mode 100644 index 5f26625b..00000000 --- a/test/FMI2/plots.jl +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using Plots - -# our simulation setup -t_start = 0.0 -t_stop = 8.0 - -# load the FMU container -fmuStruct, myFMU = getFMUStruct("SpringPendulum1D") - -# print some useful FMU-information into the REPL -fmiInfo(myFMU) - -# make an instance from the FMU -fmiInstantiate!(myFMU) - -recordValues = ["mass.s", "mass.v"] -solutionME = fmiSimulateME(myFMU, (t_start, t_stop); recordValues=recordValues, solver=FBDF(autodiff=false)) -solutionCS = fmiSimulateCS(myFMU, (t_start, t_stop); recordValues=recordValues) - -# plot the results -fig = fmiPlot(solutionME) - -fig = Plots.plot() -fmiPlot!(fig, solutionME) - -fig = fmiPlot(solutionCS) - -fig = Plots.plot() -fmiPlot!(fig, solutionCS) - -# unload the FMU, remove unpacked data on disc ("clean up") -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI2/sim_auto.jl b/test/FMI2/sim_auto.jl deleted file mode 100644 index 62dba71f..00000000 --- a/test/FMI2/sim_auto.jl +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -pathToFMU = get_model_filename("SpringPendulum1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# load FMU in temporary directory -fmuStruct, myFMU = getFMUStruct(pathToFMU) -@test isfile(myFMU.zipPath) == true -@test isdir(splitext(myFMU.zipPath)[1]) == true -fmiUnload(myFMU) - -# load FMU in source directory -fmuDir = joinpath(splitpath(pathToFMU)[1:end-1]...) -fmuStruct, myFMU = getFMUStruct(pathToFMU; unpackPath=fmuDir) -@test isfile(splitext(pathToFMU)[1] * ".zip") == true -@test isdir(splitext(pathToFMU)[1]) == true - -t_start = 0.0 -t_stop = 8.0 -dt = 1e-2 - -# test without recording values (but why?) -sol = fmiSimulate(fmuStruct, (t_start, t_stop); dt=dt) -@test sol.success - -# test with recording values -solution = fmiSimulate(fmuStruct, (t_start, t_stop); dt=dt, recordValues=["mass.s", "mass.v"], setup=true) -@test solution.success -@test length(solution.values.saveval) == length(t_start:dt:t_stop) -@test length(solution.values.saveval[1]) == 2 - -t = solution.values.t -s = collect(d[1] for d in solution.values.saveval) -v = collect(d[2] for d in solution.values.saveval) -@test t[1] == t_start -@test t[end] == t_stop - -# reference values from Simulation in Dymola2020x (Dassl) -@test s[1] == 0.5 -@test v[1] == 0.0 - -if ENV["EXPORTINGTOOL"] == "Dymola/2020x" # ToDo: Linux FMU was corrupted - @test s[end] β‰ˆ 0.509219 atol=1e-1 - @test v[end] β‰ˆ 0.314074 atol=1e-1 -end - -fmiUnload(myFMU) diff --git a/test/FMI2/sim_zero_state.jl b/test/FMI2/sim_zero_state.jl deleted file mode 100644 index 9e135fb3..00000000 --- a/test/FMI2/sim_zero_state.jl +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using DifferentialEquations: Tsit5 - -t_start = 0.0 -t_stop = 8.0 -solver=FBDF(autodiff=false) -dtmax = 0.01 - -extForce_t! = function(t, u) - u[1] = sin(t) -end - -fmuStruct, myFMU = getFMUStruct("SpringPendulumExtForce1D") - -# make a dummy zero-state FMU by overwriting the state field (ToDo: Use an actual zero state FMU from FMIZoo.jl) -myFMU.modelDescription.stateValueReferences = [] -myFMU.modelDescription.derivativeValueReferences = [] -myFMU.modelDescription.numberOfEventIndicators = 0 -myFMU.isZeroState = true - -comp = fmiInstantiate!(myFMU; loggingOn=false) -@test comp != 0 - -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = comp -end -@assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -solution = fmiSimulateME(fmuStruct, (t_start, t_stop); solver=solver, dtmax=dtmax, recordValues=["a"], inputValueReferences=myFMU.modelDescription.inputValueReferences, inputFunction=extForce_t!) -@test isnothing(solution.states) - -@test solution.values.t[1] == t_start -@test solution.values.t[end] == t_stop - -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI2/state.jl b/test/FMI2/state.jl deleted file mode 100644 index 4638f331..00000000 --- a/test/FMI2/state.jl +++ /dev/null @@ -1,55 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMI.FMIImport - -############### -# Prepare FMU # -############### - -fmuStruct, myFMU = getFMUStruct("SpringPendulum1D") - -comp = fmi2Instantiate!(myFMU; loggingOn=true) -@test comp != 0 - -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = comp -end -@assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -@test fmi2SetupExperiment(fmuStruct, 0.0) == fmi2StatusOK -@test fmi2EnterInitializationMode(fmuStruct) == fmi2StatusOK -@test fmi2ExitInitializationMode(fmuStruct) == fmi2StatusOK - -########################### -# Testing state functions # -########################### - -if fmiCanGetSetState(myFMU) - @test fmiGet(fmuStruct, "mass.s") == 0.5 - - FMUstate = fmiGetState(fmuStruct) - - fmiSet(fmuStruct, "mass.s", 10.0) - @test fmiGet(fmuStruct, "mass.s") == 10.0 - - fmiSetState(fmuStruct, FMUstate) - @test fmiGet(fmuStruct, "mass.s") == 0.5 - - fmiFreeState!(fmuStruct, FMUstate) -else - @info "The FMU provided from the tool `$(ENV["EXPORTINGTOOL"])` does not support state get and set. Skipping related tests." -end - -############ -# Clean up # -############ - -fmiUnload(myFMU) diff --git a/test/FMI3/cs_me.jl b/test/FMI3/cs_me.jl deleted file mode 100644 index 98bb0aa7..00000000 --- a/test/FMI3/cs_me.jl +++ /dev/null @@ -1,54 +0,0 @@ -############### -# Prepare FMU # -############### - -t_start = 0.0 -t_stop = 1.0 - -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") -@test fmiIsCoSimulation(myFMU) -@test fmiIsModelExchange(myFMU) -# inst = fmiInstantiate!(myFMU; loggingOn=false) -# @test inst != 0 - -# # choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = inst -end -sol = fmiSimulateCS(fmuStruct, t_start, t_stop) -@test sol.success -sol = fmiSimulateME(fmuStruct, t_start, t_stop) -@test sol.success -fmiUnload(myFMU) - -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") -inst = fmi3InstantiateModelExchange!(myFMU; loggingOn=false) -@test inst.type == FMI.fmi3TypeModelExchange -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = inst -end -sol = fmiSimulate(fmuStruct, t_start, t_stop) -@test sol.success -fmiUnload(myFMU) - -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") -inst = fmi3InstantiateCoSimulation!(myFMU; loggingOn=false) -@test inst.type == FMI.fmi3TypeCoSimulation -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = inst -end -sol = fmiSimulate(fmuStruct, t_start, t_stop) -@test sol.success -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI3/exec_config.jl b/test/FMI3/exec_config.jl deleted file mode 100644 index 59286bf0..00000000 --- a/test/FMI3/exec_config.jl +++ /dev/null @@ -1,80 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMI.FMIImport - -t_start = 0.0 -t_stop = 1.0 - -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") - -comp = fmi3InstantiateCoSimulation!(myFMU; loggingOn=false) -@test comp != 0 -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = comp -end -@assert fmuStruct !== nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -for execConf in (FMU3_EXECUTION_CONFIGURATION_NO_FREEING, FMU3_EXECUTION_CONFIGURATION_RESET, FMU3_EXECUTION_CONFIGURATION_NO_RESET) # ToDo: Add `FMU3_EXECUTION_CONFIGURATION_NOTHING` - for mode in ([:CS]) - global fmuStruct - @info "\t$(mode) | $(execConf)" - - myFMU.executionConfig = execConf - - # sim test - numInst = length(myFMU.instances) - - if mode == :CS - fmiSimulateCS(fmuStruct, t_start, t_stop) - elseif mode == :ME - fmiSimulateME(fmuStruct, t_start, t_stop) - else - @assert false "Unknown mode `$(mode)`." - end - - if execConf.instantiate - numInst += 1 - end - if execConf.freeInstance - numInst -= 1 - end - - @test length(myFMU.instances) == numInst - - # prepare next run start - if envFMUSTRUCT == "FMU" - if execConf.freeInstance - fmi3FreeInstance!(myFMU) - end - - if mode == :CS - fmi3InstantiateCoSimulation!(myFMU) - elseif mode == :ME - fmi3InstantiateModelExchange!(myFMU) - end - - elseif envFMUSTRUCT == "FMUCOMPONENT" - if execConf.freeInstance - fmi3FreeInstance!(fmuStruct) - end - if mode == :CS - fmi3InstantiateCoSimulation!(myFMU) - elseif mode == :ME - fmi3InstantiateModelExchange!(myFMU) - end - - end - # prepare next run end - - end -end - -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI3/getter_setter.jl b/test/FMI3/getter_setter.jl deleted file mode 100644 index 45c65d62..00000000 --- a/test/FMI3/getter_setter.jl +++ /dev/null @@ -1,82 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -import FMI.FMIImport.FMICore - -############### -# Prepare FMU # -############### - -myFMU = fmiLoad("Feedthrough", "ModelicaReferenceFMUs", "0.0.20", "3.0") -inst = fmi3InstantiateCoSimulation!(myFMU; loggingOn=true) -@test inst != 0 - -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = inst -end -@assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -@test fmi3EnterInitializationMode(fmuStruct) == 0 -@test fmi3ExitInitializationMode(fmuStruct) == 0 - -realValueReferences = ["Float32_continuous_input", "Float64_continuous_input"] -integerValueReferences = ["Int32_input", "Int64_input"] -booleanValueReferences = ["Boolean_input", "Boolean_output"] -stringValueReferences = ["String_parameter", "String_parameter"] - -######################### -# Testing Single Values # -######################### - -rndReal = 100 * rand() -rndInteger = round(Integer, 100 * rand()) -rndBoolean = rand() > 0.5 -rndString = Random.randstring(12) - -cacheReal = 0.0 -cacheInteger = 0 -cacheBoolean = false -cacheString = "" - -fmiSet(fmuStruct, - [realValueReferences[1], integerValueReferences[1], booleanValueReferences[1], stringValueReferences[1]], - [Float32(rndReal), rndInteger, rndBoolean, rndString]) -@test fmiGet(fmuStruct, - [realValueReferences[1], integerValueReferences[1], booleanValueReferences[1], stringValueReferences[1]]) == - [Float32(rndReal), rndInteger, FMICore.fmi3Boolean(rndBoolean), rndString] - -#@test fmiGetStartValue(fmuStruct, "p_enumeration") == "myEnumeration1" -# println(fmi3ModelVariablesForValueReference(inst.fmu.modelDescription, UInt32(29))) -@test fmiGetStartValue(fmuStruct, "String_parameter") == "Set me!" -@test fmiGetStartValue(fmuStruct, "Float32_continuous_input") == 0.0 - -################## -# Testing Arrays # -################## - -rndReal = [100 * rand(), 100 * rand()] -rndInteger = [round(Integer, 100 * rand()), round(Integer, 100 * rand())] -rndBoolean = [(rand() > 0.5), (rand() > 0.5)] -tmp = Random.randstring(8) -rndString = [tmp, tmp] - -cacheReal = [0.0, 0.0] -cacheInteger = [FMI.fmi3Int32(0), FMI.fmi3Int32(0)] -cacheBoolean = [FMI.fmi3Boolean(false), FMI.fmi3Boolean(false)] -cacheString = [pointer(""), pointer("")] - -#@test fmiGetStartValue(fmuStruct, ["p_enumeration", "p_string", "p_real"]) == ["myEnumeration1", "Hello World!", 0.0] -@test fmiGetStartValue(fmuStruct, ["String_parameter", "Float32_continuous_input"]) == ["Set me!", 0.0] - -############ -# Clean up # -############ - -fmiUnload(myFMU) diff --git a/test/FMI3/load_save.jl b/test/FMI3/load_save.jl deleted file mode 100644 index e202d922..00000000 --- a/test/FMI3/load_save.jl +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using JLD2 - -# our simulation setup -t_start = 0.0 -t_stop = 8.0 - -# load the FMU container -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") - -recordValues = ["h", "v"] -solutionME = fmiSimulateME(myFMU, t_start, t_stop; recordValues=recordValues) -solutionCS = fmiSimulateCS(myFMU, t_start, t_stop; recordValues=recordValues) - -# ME - -fmiSaveSolution(solutionME, "solutionME.jld2") - -#@warn "Loading solution tests are disabled for now." -#anotherSolutionME = solutionME -anotherSolutionME = fmiLoadSolution("solutionME.jld2") - -@test solutionME.success == true -@test solutionME.success == anotherSolutionME.success -@test solutionME.states.u == anotherSolutionME.states.u -@test solutionME.states.t == anotherSolutionME.states.t -@test solutionME.values.saveval == anotherSolutionME.values.saveval -@test solutionME.values.t == anotherSolutionME.values.t - -# ME-BONUS: events -@test solutionME.events == anotherSolutionME.events - -# CS - -fmiSaveSolution(solutionCS, "solutionCS.jld2") - -#@warn "Loading solution tests are disabled for now." -#anotherSolutionCS = solutionCS -anotherSolutionCS = fmiLoadSolution("solutionCS.jld2") - -@test solutionCS.success == true -@test solutionCS.success == anotherSolutionCS.success -@test solutionCS.values.saveval == anotherSolutionCS.values.saveval -@test solutionCS.values.t == anotherSolutionCS.values.t - -# unload the FMU, remove unpacked data on disc ("clean up") -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI3/plots.jl b/test/FMI3/plots.jl deleted file mode 100644 index 53b6ebbd..00000000 --- a/test/FMI3/plots.jl +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using Plots - -# our simulation setup -t_start = 0.0 -t_stop = 8.0 - -# load the FMU container -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") - -# print some useful FMU-information into the REPL -fmiInfo(myFMU) - -# make an instance from the FMU -fmi3InstantiateCoSimulation!(myFMU) - -recordValues = ["h", "v"] -# solutionME = fmiSimulateME(myFMU, t_start, t_stop; recordValues=recordValues) -solutionCS = fmiSimulateCS(myFMU, t_start, t_stop; recordValues=recordValues) - -# plot the results -# fig = fmiPlot(solutionME) - -# fig = Plots.plot() -# fmiPlot!(fig, solutionME) - -fig = fmiPlot(solutionCS) - -fig = Plots.plot() -fmiPlot!(fig, solutionCS) - -# unload the FMU, remove unpacked data on disc ("clean up") -fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI3/sim_CS.jl b/test/FMI3/sim_CS.jl deleted file mode 100644 index 9c7236a1..00000000 --- a/test/FMI3/sim_CS.jl +++ /dev/null @@ -1,87 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -# case 1: CS-FMU Simulation - -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") - -comp = fmi3InstantiateCoSimulation!(myFMU; loggingOn=false) -@test comp != 0 - -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = comp -end -@assert fmuStruct !== nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -t_start = 0.0 -t_stop = 3.0 - -# test without recording values (but why?) -# solution = fmiSimulateCS(fmuStruct, t_start, t_stop) -# @test solution.success - -# test with recording values -solution = fmiSimulateCS(fmuStruct, t_start, t_stop; dt=1e-2, recordValues=["h", "v"]) -@test solution.success -@test length(solution.values.saveval) == t_start:1e-2:t_stop |> length -@test length(solution.values.saveval[1]) == 2 - -t = solution.values.t -s = collect(d[1] for d in solution.values.saveval) -v = collect(d[2] for d in solution.values.saveval) -@test t[1] == t_start -@test t[end] == t_stop - - -# reference values from Simulation in Dymola2020x (Dassl) -@test s[1] == 1.0 -@test v[1] == 0.0 - -if ENV["EXPORTINGTOOL"] == "ModelicaReferenceFMUs" # ToDo: Linux FMU was corrupted - @test s[end] β‰ˆ 0.0 atol=1e-1 - @test v[end] β‰ˆ 0.0 atol=1e-1 -end - -fmiUnload(myFMU) - -# case 2: CS-FMU with input signal not supported with BouncingBall FMU - -# function extForce(t) -# [sin(t)] -# end - -# myFMU = fmiLoad("SpringPendulumExtForce1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# comp = fmiInstantiate!(myFMU; loggingOn=false) -# @test comp != 0 - -# # choose FMU or FMUComponent -# fmuStruct = nothing -# envFMUSTRUCT = ENV["FMUSTRUCT"] -# if envFMUSTRUCT == "FMU" -# fmuStruct = myFMU -# elseif envFMUSTRUCT == "FMUCOMPONENT" -# fmuStruct = comp -# end -# @assert fmuStruct !== nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -# solution = fmiSimulateCS(fmuStruct, t_start, t_stop; dt=1e-2, recordValues=["mass.s", "mass.v"], inputValueReferences=["extForce"], inputFunction=extForce) -# @test solution.success -# @test length(solution.values.saveval) > 0 -# @test length(solution.values.t) > 0 - -# @test t[1] == t_start -# @test t[end] == t_stop - -# # reference values from Simulation in Dymola2020x (Dassl) -# @test [solution.values.saveval[1]...] == [0.5, 0.0] -# @test sum(abs.([solution.values.saveval[end]...] - [0.613371, 0.188633])) < 0.2 -# fmiUnload(myFMU) - diff --git a/test/FMI3/sim_ME.jl b/test/FMI3/sim_ME.jl deleted file mode 100644 index 8f8918bc..00000000 --- a/test/FMI3/sim_ME.jl +++ /dev/null @@ -1,261 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using DifferentialEquations: Tsit5, Rosenbrock23 - -t_start = 0.0 -t_stop = 3.0 - -# case 1: ME-FMU with state events - -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") - -comp = fmi3InstantiateModelExchange!(myFMU; loggingOn=false) -@test comp != 0 - -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = comp -end -@assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -solution = fmiSimulateME(fmuStruct, t_start, t_stop) -@test length(solution.states.u) > 0 -@test length(solution.states.t) > 0 - -@test solution.states.t[1] == t_start -@test solution.states.t[end] == t_stop - -# reference values from Simulation in Dymola2020x (Dassl) -@test solution.states.u[1] == [1.0, 0.0] -@test sum(abs.(solution.states.u[end] - [1.0, 0.0])) < 0.1 -fmiUnload(myFMU) - -# case 2: ME-FMU with state and time events - -# myFMU = fmiLoad("SpringTimeFrictionPendulum1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# comp = fmiInstantiate!(myFMU; loggingOn=false) -# @test comp != 0 - -# # choose FMU or FMUComponent -# fmuStruct = nothing -# envFMUSTRUCT = ENV["FMUSTRUCT"] -# if envFMUSTRUCT == "FMU" -# fmuStruct = myFMU -# elseif envFMUSTRUCT == "FMUCOMPONENT" -# fmuStruct = comp -# end -# @assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -# ### test without recording values - -# solution = fmiSimulateME(fmuStruct, t_start, t_stop; dtmax=0.001) # dtmax to force resolution -# @test length(solution.states.u) > 0 -# @test length(solution.states.t) > 0 - -# @test solution.states.t[1] == t_start -# @test solution.states.t[end] == t_stop - -# # reference values from Simulation in Dymola2020x (Dassl) -# @test solution.states.u[1] == [0.5, 0.0] -# @test sum(abs.(solution.states.u[end] - [1.05444, 1e-10])) < 0.01 - -# ### test with recording values (variable step record values) - -# solution= fmiSimulateME(fmuStruct, t_start, t_stop; recordValues="mass.f", dtmax=0.001) # dtmax to force resolution -# dataLength = length(solution.states.u) -# @test dataLength > 0 -# @test length(solution.states.t) == dataLength -# @test length(solution.values.saveval) == dataLength -# @test length(solution.values.t) == dataLength - -# @test solution.states.t[1] == t_start -# @test solution.states.t[end] == t_stop -# @test solution.values.t[1] == t_start -# @test solution.values.t[end] == t_stop - -# # reference values from Simulation in Dymola2020x (Dassl) -# @test sum(abs.(solution.states.u[1] - [0.5, 0.0])) < 1e-4 -# @test sum(abs.(solution.states.u[end] - [1.05444, 1e-10])) < 0.01 -# @test abs(solution.values.saveval[1][1] - 0.75) < 1e-4 -# @test sum(abs.(solution.values.saveval[end][1] - -0.54435 )) < 0.015 - -# ### test with recording values (fixed step record values) - -# tData = t_start:0.1:t_stop -# solution = fmiSimulateME(fmuStruct, t_start, t_stop; recordValues="mass.f", saveat=tData, dtmax=0.001) # dtmax to force resolution -# @test length(solution.states.u) == length(tData) -# @test length(solution.states.t) == length(tData) -# @test length(solution.values.saveval) == length(tData) -# @test length(solution.values.t) == length(tData) - -# @test solution.states.t[1] == t_start -# @test solution.states.t[end] == t_stop -# @test solution.values.t[1] == t_start -# @test solution.values.t[end] == t_stop - -# # reference values from Simulation in Dymola2020x (Dassl) -# @test sum(abs.(solution.states.u[1] - [0.5, 0.0])) < 1e-4 -# @test sum(abs.(solution.states.u[end] - [1.05444, 1e-10])) < 0.01 -# @test abs(solution.values.saveval[1][1] - 0.75) < 1e-4 -# @test sum(abs.(solution.values.saveval[end][1] - -0.54435 )) < 0.015 - -# fmiUnload(myFMU) - -# # case 3a: ME-FMU without events, but with input signal (explicit solver: Tsit5) - -# function extForce(t) -# [sin(t)] -# end - -# myFMU = fmiLoad("SpringPendulumExtForce1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# comp = fmiInstantiate!(myFMU; loggingOn=false) -# @test comp != 0 - -# # choose FMU or FMUComponent -# fmuStruct = nothing -# envFMUSTRUCT = ENV["FMUSTRUCT"] -# if envFMUSTRUCT == "FMU" -# fmuStruct = myFMU -# elseif envFMUSTRUCT == "FMUCOMPONENT" -# fmuStruct = comp -# end -# @assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -# solution = fmiSimulateME(fmuStruct, t_start, t_stop; inputValueReferences=["extForce"], inputFunction=extForce, solver=Tsit5(), dtmax=0.001) # dtmax to force resolution -# @test length(solution.states.u) > 0 -# @test length(solution.states.t) > 0 - -# @test solution.states.t[1] == t_start -# @test solution.states.t[end] == t_stop - -# # reference values from Simulation in Dymola2020x (Dassl) -# @test solution.states.u[1] == [0.5, 0.0] -# @test sum(abs.(solution.states.u[end] - [0.613371, 0.188633])) < 0.012 -# fmiUnload(myFMU) - -# # case 3b: ME-FMU without events, but with input signal (implicit solver: Rosenbrock23, autodiff) - -# myFMU = fmiLoad("SpringPendulumExtForce1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# comp = fmiInstantiate!(myFMU; loggingOn=false) -# @test comp != 0 - -# # choose FMU or FMUComponent -# fmuStruct = nothing -# envFMUSTRUCT = ENV["FMUSTRUCT"] -# if envFMUSTRUCT == "FMU" -# fmuStruct = myFMU -# elseif envFMUSTRUCT == "FMUCOMPONENT" -# fmuStruct = comp -# end -# @assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -# # ToDo: autodiff=true not working currently! -# # solution = fmiSimulateME(fmuStruct, t_start, t_stop; inputValueReferences=["extForce"], inputFunction=extForce, solver=Rosenbrock23(autodiff=true), dtmax=0.001) # dtmax to force resolution -# # @test length(solution.states.u) > 0 -# # @test length(solution.states.t) > 0 - -# # @test solution.states.t[1] == t_start -# # @test solution.states.t[end] == t_stop - -# # # reference values from Simulation in Dymola2020x (Dassl) -# # @test solution.states.u[1] == [0.5, 0.0] -# # @test sum(abs.(solution.states.u[end] - [0.613371, 0.188633])) < 0.01 -# fmiUnload(myFMU) - -# # case 3c: ME-FMU without events, but with input signal (implicit solver: Rosenbrock23, no autodiff) - -# myFMU = fmiLoad("SpringPendulumExtForce1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# comp = fmiInstantiate!(myFMU; loggingOn=false) -# @test comp != 0 - -# # choose FMU or FMUComponent -# fmuStruct = nothing -# envFMUSTRUCT = ENV["FMUSTRUCT"] -# if envFMUSTRUCT == "FMU" -# fmuStruct = myFMU -# elseif envFMUSTRUCT == "FMUCOMPONENT" -# fmuStruct = comp -# end -# @assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -# solution = fmiSimulateME(fmuStruct, t_start, t_stop; inputValueReferences=["extForce"], inputFunction=extForce, solver=Rosenbrock23(autodiff=false), dtmax=0.001) # dtmax to force resolution -# @test length(solution.states.u) > 0 -# @test length(solution.states.t) > 0 - -# @test solution.states.t[1] == t_start -# @test solution.states.t[end] == t_stop - -# # reference values from Simulation in Dymola2020x (Dassl) -# @test solution.states.u[1] == [0.5, 0.0] -# @test sum(abs.(solution.states.u[end] - [0.613371, 0.188633])) < 0.01 -# fmiUnload(myFMU) - -# # case 4: ME-FMU without events, but saving value interpolation - -# myFMU = fmiLoad("SpringPendulumExtForce1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# comp = fmiInstantiate!(myFMU; loggingOn=false) -# @test comp != 0 - -# # choose FMU or FMUComponent -# fmuStruct = nothing -# envFMUSTRUCT = ENV["FMUSTRUCT"] -# if envFMUSTRUCT == "FMU" -# fmuStruct = myFMU -# elseif envFMUSTRUCT == "FMUCOMPONENT" -# fmuStruct = comp -# end -# @assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -# solution = fmiSimulateME(fmuStruct, t_start, t_stop; saveat=tData, recordValues=myFMU.modelDescription.stateValueReferences) -# @test length(solution.states.u) == length(tData) -# @test length(solution.states.t) == length(tData) -# @test length(solution.values.saveval) == length(tData) -# @test length(solution.values.t) == length(tData) - -# for i in 1:length(tData) -# @test sum(abs(solution.states.t[i] - solution.states.t[i])) < 1e-6 -# @test sum(abs(solution.states.u[i][1] - solution.values.saveval[i][1])) < 1e-6 -# @test sum(abs(solution.states.u[i][2] - solution.values.saveval[i][2])) < 1e-6 -# end - -# fmiUnload(myFMU) - -# # case 5: ME-FMU with different (random) start state - -# myFMU = fmiLoad("SpringFrictionPendulum1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) - -# comp = fmiInstantiate!(myFMU; loggingOn=false) -# @test comp != 0 - -# # choose FMU or FMUComponent -# fmuStruct = nothing -# envFMUSTRUCT = ENV["FMUSTRUCT"] -# if envFMUSTRUCT == "FMU" -# fmuStruct = myFMU -# elseif envFMUSTRUCT == "FMUCOMPONENT" -# fmuStruct = comp -# end -# @assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -# rand_x0 = rand(2) -# solution = fmiSimulateME(fmuStruct, t_start, t_stop; x0=rand_x0) -# @test length(solution.states.u) > 0 -# @test length(solution.states.t) > 0 - -# @test solution.states.t[1] == t_start -# @test solution.states.t[end] == t_stop - -# @test solution.states.u[1] == rand_x0 -# fmiUnload(myFMU) \ No newline at end of file diff --git a/test/FMI3/sim_auto.jl b/test/FMI3/sim_auto.jl deleted file mode 100644 index 193cfadc..00000000 --- a/test/FMI3/sim_auto.jl +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -pathToFMU = get_model_filename("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") - -# load FMU in temporary directory -myFMU = fmiLoad(pathToFMU) -@test isfile(myFMU.zipPath) == true -@test isdir(splitext(myFMU.zipPath)[1]) == true -fmiUnload(myFMU) - -# load FMU in source directory -fmuDir = joinpath(splitpath(pathToFMU)[1:end-1]...) -myFMU = fmiLoad(pathToFMU; unpackPath=fmuDir) -@test isfile(splitext(pathToFMU)[1] * ".zip") == true -@test isdir(splitext(pathToFMU)[1]) == true - -comp = fmiInstantiate!(myFMU; loggingOn=false) -@test comp != 0 - -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = comp -end -@assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -t_start = 0.0 -t_stop = 8.0 - -# test without recording values (but why?) -sol = fmiSimulate(fmuStruct, t_start, t_stop; dt=1e-2) -@test sol.success - -# test with recording values -solution = fmiSimulate(fmuStruct, t_start, t_stop; dt=1e-2, recordValues=["mass.s", "mass.v"], setup=true) -@test solution.success -@test length(solution.values.saveval) == t_start:1e-2:t_stop |> length -@test length(solution.values.saveval[1]) == 2 - -t = solution.values.t -s = collect(d[1] for d in solution.values.saveval) -v = collect(d[2] for d in solution.values.saveval) -@test t[1] == t_start -@test t[end] == t_stop - -# reference values from Simulation in Dymola2020x (Dassl) -@test s[1] == 0.5 -@test v[1] == 0.0 - -if ENV["EXPORTINGTOOL"] == "Dymola/2020x" # ToDo: Linux FMU was corrupted - @test s[end] β‰ˆ 0.509219 atol=1e-1 - @test v[end] β‰ˆ 0.314074 atol=1e-1 -end - -fmiUnload(myFMU) diff --git a/test/FMI3/state.jl b/test/FMI3/state.jl deleted file mode 100644 index ec4ebcb7..00000000 --- a/test/FMI3/state.jl +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher -# Licensed under the MIT license. See LICENSE file in the project root for details. -# - -using FMI.FMIImport - -############### -# Prepare FMU # -############### - -myFMU = fmiLoad("BouncingBall", "ModelicaReferenceFMUs", "0.0.20", "3.0") - -inst = fmi3InstantiateCoSimulation!(myFMU; loggingOn=true) -@test inst != 0 - -# choose FMU or FMUComponent -fmuStruct = nothing -envFMUSTRUCT = ENV["FMUSTRUCT"] -if envFMUSTRUCT == "FMU" - fmuStruct = myFMU -elseif envFMUSTRUCT == "FMUCOMPONENT" - fmuStruct = inst -end -@assert fmuStruct != nothing "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - -@test fmi3EnterInitializationMode(fmuStruct) == 0 -@test fmi3ExitInitializationMode(fmuStruct) == 0 - -########################### -# Testing state functions # -########################### - -if fmiCanGetSetState(myFMU) - @test fmiGet(fmuStruct, "h") == 1 - - FMUstate = fmiGetState(fmuStruct) - - fmiSet(fmuStruct, "h", 10.0) - @test fmiGet(fmuStruct, "h") == 10.0 - - fmiSetState(fmuStruct, FMUstate) - @test fmiGet(fmuStruct, "h") == 1 - - fmiFreeState!(fmuStruct, FMUstate) -else - @info "The FMU provided from the tool `$(ENV["EXPORTINGTOOL"])` does not support state get, set, serialization and deserialization. Skipping related tests." -end - -############ -# Clean up # -############ - -fmiUnload(myFMU) diff --git a/test/FMI2/eval.jl b/test/eval.jl similarity index 75% rename from test/FMI2/eval.jl rename to test/eval.jl index fdd73692..ae2f2813 100644 --- a/test/FMI2/eval.jl +++ b/test/eval.jl @@ -1,18 +1,18 @@ -using PkgEval -using FMI -using Test - -config = Configuration(; julia="1.8", time_limit=120*60); - -package = Package(; name="FMI"); - -@info "PkgEval" -result = evaluate([config], [package]) - -@info "Result" -println(result) - -@info "Log" -println(result[1, :log]) - -@test result[1, :status] == :ok +using PkgEval +using FMI +using Test + +config = Configuration(; julia="1.10", time_limit=120*60); + +package = Package(; name="FMI"); + +@info "PkgEval" +result = evaluate([config], [package]) + +@info "Result" +println(result) + +@info "Log" +println(result[1, :log]) + +@test result[1, :status] == :ok diff --git a/test/runtests.jl b/test/runtests.jl index 2de20adc..5a439d04 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -9,175 +9,95 @@ using Test using Aqua import Random -import FMI.FMIImport.FMICore: fmi2StatusOK, fmi3StatusOK, fmi2ComponentStateTerminated, fmi2ComponentStateInstantiated, fmi3Boolean -import FMI.FMIImport.FMICore: FMU2_EXECUTION_CONFIGURATION_NO_FREEING, FMU2_EXECUTION_CONFIGURATION_NO_RESET, FMU2_EXECUTION_CONFIGURATION_RESET, FMU2_EXECUTION_CONFIGURATION_NOTHING +using FMI.FMIImport +using FMI.FMIImport.FMIBase +using FMI.FMIImport.FMIBase.FMICore + +import FMI.FMIImport.FMIBase: FMU_EXECUTION_CONFIGURATIONS + using FMI.FMIImport using DifferentialEquations: FBDF -exportingToolsWindows = [("Dymola", "2022x")] -exportingToolsLinux = [("Dymola", "2022x")] -fmuStructs = ["FMU", "FMUCOMPONENT"] +fmuStructs = ("FMU", "FMUCOMPONENT") # enable assertions for warnings/errors for all default execution configurations -for exec in [FMU2_EXECUTION_CONFIGURATION_NO_FREEING, FMU2_EXECUTION_CONFIGURATION_NO_RESET, FMU2_EXECUTION_CONFIGURATION_RESET, FMU2_EXECUTION_CONFIGURATION_NOTHING, FMU3_EXECUTION_CONFIGURATION_NO_FREEING, FMU3_EXECUTION_CONFIGURATION_NO_RESET, FMU3_EXECUTION_CONFIGURATION_RESET] +for exec in FMU_EXECUTION_CONFIGURATIONS exec.assertOnError = true exec.assertOnWarning = true end -function getFMUStruct(modelname, tool=ENV["EXPORTINGTOOL"], version=ENV["EXPORTINGVERSION"]; kwargs...) +function getFMUStruct(modelname, mode, tool=ENV["EXPORTINGTOOL"], version=ENV["EXPORTINGVERSION"], fmiversion=ENV["FMIVERSION"], fmustruct=ENV["FMUSTRUCT"]; kwargs...) # choose FMU or FMUComponent if endswith(modelname, ".fmu") - fmu = fmiLoad(modelname; kwargs...) + fmu = loadFMU(modelname; kwargs...) else - fmu = fmiLoad(modelname, tool, version; kwargs...) + fmu = loadFMU(modelname, tool, version, fmiversion; kwargs...) end - envFMUSTRUCT = ENV["FMUSTRUCT"] - - if envFMUSTRUCT == "FMU" + if fmustruct == "FMU" return fmu, fmu - elseif envFMUSTRUCT == "FMUCOMPONENT" - comp = fmiInstantiate!(fmu; loggingOn=false) - @test comp != 0 - return comp, fmu + elseif fmustruct == "FMUCOMPONENT" + inst, _ = FMI.prepareSolveFMU(fmu, nothing, mode; loggingOn=true) + @test !isnothing(inst) + return inst, fmu else - @assert false "Unknown fmuStruct, environment variable `FMUSTRUCT` = `$envFMUSTRUCT`" - end -end - -function runtestsFMI2(exportingTool) - ENV["EXPORTINGTOOL"] = exportingTool[1] - ENV["EXPORTINGVERSION"] = exportingTool[2] - - @testset "Testing FMUs exported from $exportingTool" begin - - for str in fmuStructs - @testset "Functions for $str" begin - ENV["FMUSTRUCT"] = str - - @info "Variable Getters / Setters (getter_setter.jl)" - @testset "Variable Getters / Setters" begin - include("FMI2/getter_setter.jl") - end - - @info "Execution Configurations (exec_config.jl)" - @testset "Execution Configurations" begin - include("FMI2/exec_config.jl") - end - - @info "State Manipulation (state.jl)" - @testset "State Manipulation" begin - include("FMI2/state.jl") - end - - @info "Automatic Simulation (sim_auto.jl)" - @testset "Automatic Simulation (CS or ME)" begin - include("FMI2/sim_auto.jl") - end - - @info "CS Simulation (sim_CS.jl)" - @testset "CS Simulation" begin - include("FMI2/sim_CS.jl") - end - - @info "ME Simulation (sim_ME.jl)" - @testset "ME Simulation" begin - include("FMI2/sim_ME.jl") - end - - @info "Support CS and ME simultaneously (cs_me.jl)" - @testset "Support CS and ME simultaneously" begin - include("FMI2/cs_me.jl") - end - - @info "Simulation FMU without states (sim_zero_state.jl)" - @testset "Simulation FMU without states" begin - include("FMI2/sim_zero_state.jl") - end - - @info "Loading/Saving simulation results (load_save.jl)" - @testset "Loading/Saving simulation results" begin - include("FMI2/load_save.jl") - end - end - end - - # if VERSION >= v"1.9.0" - # @info "Performance (performance.jl)" - # @testset "Performance" begin - # include("FMI2/performance.jl") - # end - # else - @info "Julia Version $(VERSION), skipping performance tests ..." - #end - - @info "Plotting (plots.jl)" - @testset "Plotting" begin - include("FMI2/plots.jl") - end + @assert false "Unknown fmuStruct, variable `FMUSTRUCT` = `$(fmustruct)`" end end -function runtestsFMI3(exportingTool) - ENV["EXPORTINGTOOL"] = exportingTool[1] - ENV["EXPORTINGVERSION"] = exportingTool[2] - - @testset "Testing FMUs exported from $exportingTool" begin - - for str in fmuStructs - @testset "Functions for $str" begin - ENV["FMUSTRUCT"] = str - @testset "Variable Getters / Setters (getter_setter.jl)" begin - include("FMI3/getter_setter.jl") - end - - @info "Execution Configurations (exec_config.jl)" - @testset "Execution Configurations" begin - include("FMI3/exec_config.jl") - end - - @testset "State Manipulation (state.jl)" begin - include("FMI3/state.jl") - end - - @testset "CS Simulation (sim_CS.jl)" begin - include("FMI3/sim_CS.jl") - end - @testset "ME Simulation (sim_ME.jl)" begin - include("FMI3/sim_ME.jl") - end - @testset "Support CS and ME simultaneously (cs_me.jl)" begin - include("FMI3/cs_me.jl") - end - @testset "Loading/Saving simulation results (load_save.jl)" begin - include("FMI3/load_save.jl") +@testset "FMI.jl" begin + if Sys.iswindows() || Sys.islinux() + @info "Automated testing is supported on Windows/Linux." + + ENV["EXPORTINGTOOL"] = "Dymola" + ENV["EXPORTINGVERSION"] = "2023x" + + for fmiversion in (2.0, 3.0) + ENV["FMIVERSION"] = fmiversion + + @testset "Testing FMI $(ENV["FMIVERSION"]) FMUs exported from $(ENV["EXPORTINGTOOL"]) $(ENV["EXPORTINGVERSION"])" begin + + for fmustruct in fmuStructs + ENV["FMUSTRUCT"] = fmustruct + + @testset "Functions for $(ENV["FMUSTRUCT"])" begin + + @info "CS Simulation (sim_CS.jl)" + @testset "CS Simulation" begin + include("sim_CS.jl") + end + + @info "ME Simulation (sim_ME.jl)" + @testset "ME Simulation" begin + include("sim_ME.jl") + end + + @info "SE Simulation (sim_SE.jl)" + @testset "SE Simulation" begin + include("sim_SE.jl") + end + + @info "Simulation FMU without states (sim_zero_state.jl)" + @testset "Simulation FMU without states" begin + include("sim_zero_state.jl") + end + end + + # if VERSION >= v"1.9.0" + # @info "Performance (performance.jl)" + # @testset "Performance" begin + # include("FMI2/performance.jl") + # end + # else + @info "Julia Version $(VERSION), skipping performance tests ..." + #end end end end - - @testset "Plotting (plots.jl)" begin - include("FMI3/plots.jl") - end - end -end - -@testset "FMI.jl" begin - if Sys.iswindows() - @info "Automated testing is supported on Windows." - for exportingTool in exportingToolsWindows - runtestsFMI2(exportingTool) - #runtestsFMI3(exportingTool) - end - elseif Sys.islinux() - @info "Automated testing is supported on Linux." - for exportingTool in exportingToolsLinux - runtestsFMI2(exportingTool) - #runtestsFMI3(exportingTool) - end elseif Sys.isapple() @warn "Test-sets are currently using Windows- and Linux-FMUs, automated testing for macOS is currently not supported." end diff --git a/test/FMI2/sim_CS.jl b/test/sim_CS.jl similarity index 50% rename from test/FMI2/sim_CS.jl rename to test/sim_CS.jl index 6d85c515..819c48ca 100644 --- a/test/FMI2/sim_CS.jl +++ b/test/sim_CS.jl @@ -3,19 +3,21 @@ # Licensed under the MIT license. See LICENSE file in the project root for details. # +# testing different modes for CS (co simulation) mode + # case 1: CS-FMU Simulation -fmuStruct, myFMU = getFMUStruct("SpringPendulum1D") +fmuStruct, fmu = getFMUStruct("SpringPendulum1D", :CS) t_start = 0.0 t_stop = 8.0 -# test without recording values (but why?) -solution = fmiSimulateCS(fmuStruct, (t_start, t_stop); dt=1e-2) +# test without recording values (just for completeness) +solution = simulateCS(fmuStruct, (t_start, t_stop); dt=1e-2) @test solution.success # test with recording values -solution = fmiSimulateCS(fmuStruct, (t_start, t_stop); dt=1e-2, recordValues=["mass.s", "mass.v"]) +solution = simulateCS(fmuStruct, (t_start, t_stop); dt=1e-2, recordValues=["mass.s", "mass.v"]) @test solution.success @test length(solution.values.saveval) == t_start:1e-2:t_stop |> length @test length(solution.values.saveval[1]) == 2 @@ -26,33 +28,31 @@ v = collect(d[2] for d in solution.values.saveval) @test t[1] == t_start @test t[end] == t_stop -# reference values from Simulation in Dymola2020x (Dassl) +# reference values from Simulation in Dymola2020x (Dassl, default settings) @test s[1] == 0.5 @test v[1] == 0.0 -if ENV["EXPORTINGTOOL"] == "Dymola/2020x" # ToDo: Linux FMU was corrupted - @test s[end] β‰ˆ 0.509219 atol=1e-1 - @test v[end] β‰ˆ 0.314074 atol=1e-1 -end +@test isapprox(s[end], 0.509219; atol=1e-1) +@test isapprox(v[end], 0.314074; atol=1e-1) -fmiUnload(myFMU) +unloadFMU(fmu) # case 2: CS-FMU with input signal -extForce_t = function (t::Real, u::AbstractArray{<:Real}) +extForce_t! = function (t::Real, u::AbstractArray{<:Real}) u[1] = sin(t) end -extForce_ct = function (c::Union{FMU2Component, Nothing}, t::Real, u::AbstractArray{<:Real}) +extForce_ct! = function (c::Union{FMUInstance, Nothing}, t::Real, u::AbstractArray{<:Real}) u[1] = sin(t) end -fmuStruct, myFMU = getFMUStruct("SpringPendulumExtForce1D") +fmustruct, fmu = getFMUStruct("SpringPendulumExtForce1D", :CS) -for inpfct in [extForce_ct, extForce_t] +for inpfct! in [extForce_ct!, extForce_t!] global solution - solution = fmiSimulateCS(fmuStruct, (t_start, t_stop); dt=1e-2, recordValues=["mass.s", "mass.v"], inputValueReferences=["extForce"], inputFunction=inpfct) + solution = simulateCS(fmustruct, (t_start, t_stop); dt=1e-2, recordValues=["mass.s", "mass.v"], inputValueReferences=["extForce"], inputFunction=inpfct!) @test solution.success @test length(solution.values.saveval) > 0 @test length(solution.values.t) > 0 @@ -61,8 +61,8 @@ for inpfct in [extForce_ct, extForce_t] @test t[end] == t_stop end -# reference values from Simulation in Dymola2020x (Dassl) +# reference values from Simulation in Dymola2020x (Dassl, default settings) @test [solution.values.saveval[1]...] == [0.5, 0.0] @test sum(abs.([solution.values.saveval[end]...] - [0.613371, 0.188633])) < 0.2 -fmiUnload(myFMU) +unloadFMU(fmu) diff --git a/test/FMI2/sim_ME.jl b/test/sim_ME.jl similarity index 64% rename from test/FMI2/sim_ME.jl rename to test/sim_ME.jl index 2c2a1be9..05faa8c5 100644 --- a/test/FMI2/sim_ME.jl +++ b/test/sim_ME.jl @@ -3,12 +3,14 @@ # Licensed under the MIT license. See LICENSE file in the project root for details. # +# testing different modes for ME (model exchange) mode + using DifferentialEquations using Sundials # to use autodiff! using FMISensitivity -using FMI.FMIImport.FMICore: sense_setindex! +using FMI.FMIImport.FMIBase: sense_setindex! t_start = 0.0 t_stop = 8.0 @@ -18,11 +20,11 @@ rand_x0 = rand(2) kwargs = Dict(:dtmin => 1e-64, :abstol => 1e-8, :reltol => 1e-6, :dt => 1e-32) solvers = [Tsit5(), Rodas5(autodiff=false)] # [Tsit5(), FBDF(autodiff=false), FBDF(autodiff=true), Rodas5(autodiff=false), Rodas5(autodiff=true)] -extForce_t = function(t::Real, u::AbstractArray{<:Real}) +extForce_t! = function(t::Real, u::AbstractArray{<:Real}) sense_setindex!(u, sin(t), 1) end -extForce_cxt = function(c::Union{FMU2Component, Nothing}, x::Union{AbstractArray{<:Real}, Nothing}, t::Real, u::AbstractArray{<:Real}) +extForce_cxt! = function(c::Union{FMUInstance, Nothing}, x::Union{AbstractArray{<:Real}, Nothing}, t::Real, u::AbstractArray{<:Real}) x1 = 0.0 if x != nothing x1 = x[1] @@ -38,9 +40,9 @@ for solver in solvers # case 1: ME-FMU with state events - fmuStruct, fmu = getFMUStruct("SpringFrictionPendulum1D") + fmuStruct, fmu = getFMUStruct("SpringFrictionPendulum1D", :ME) - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); solver=solver, kwargs...) + solution = simulateME(fmuStruct, (t_start, t_stop); solver=solver, kwargs...) @test length(solution.states.u) > 0 @test length(solution.states.t) > 0 @@ -50,15 +52,15 @@ for solver in solvers # reference values from Simulation in Dymola2020x (Dassl) @test solution.states.u[1] == [0.5, 0.0] @test sum(abs.(solution.states.u[end] - [1.06736, -1.03552e-10])) < 0.1 - fmiUnload(fmu) + unloadFMU(fmu) # case 2: ME-FMU with state and time events - fmuStruct, fmu = getFMUStruct("SpringTimeFrictionPendulum1D") + fmuStruct, fmu = getFMUStruct("SpringTimeFrictionPendulum1D", :ME) ### test without recording values - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); solver=solver, kwargs...) + solution = simulateME(fmuStruct, (t_start, t_stop); solver=solver, kwargs...) @test length(solution.states.u) > 0 @test length(solution.states.t) > 0 @@ -71,7 +73,7 @@ for solver in solvers ### test with recording values (variable step record values) - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); recordValues="mass.f", solver=solver, kwargs...) + solution = simulateME(fmuStruct, (t_start, t_stop); recordValues="mass.f", solver=solver, kwargs...) dataLength = length(solution.states.u) @test dataLength > 0 @test length(solution.states.t) == dataLength @@ -84,11 +86,11 @@ for solver in solvers @test solution.values.t[end] == t_stop # value/state getters - @test solution.states.t == fmi2GetSolutionTime(solution) - @test collect(s[1] for s in solution.values.saveval) == fmi2GetSolutionValue(solution, 1; isIndex=true) - @test collect(u[1] for u in solution.states.u ) == fmi2GetSolutionState(solution, 1; isIndex=true) - @test isapprox(fmi2GetSolutionState(solution, 2; isIndex=true), fmi2GetSolutionDerivative(solution, 1; isIndex=true); atol=1e-1) # tolerance is large, because Rosenbrock23 solution derivative is not that accurate (other solvers reach 1e-4 for this example) - @info "Max error of solver polynomial derivative: $(max(abs.(fmi2GetSolutionState(solution, 2; isIndex=true) .- fmi2GetSolutionDerivative(solution, 1; isIndex=true))...))" + @test solution.states.t == getTime(solution) + @test collect(s[1] for s in solution.values.saveval) == getValue(solution, 1; isIndex=true) + @test collect(u[1] for u in solution.states.u ) == getState(solution, 1; isIndex=true) + @test isapprox(getState(solution, 2; isIndex=true), getStateDerivative(solution, 1; isIndex=true); atol=1e-1) # tolerance is large, because Rosenbrock23 solution derivative is not that accurate (other solvers reach 1e-4 for this example) + @info "Max error of solver polynominal derivative: $(max(abs.(getState(solution, 2; isIndex=true) .- getStateDerivative(solution, 1; isIndex=true))...))" # reference values from Simulation in Dymola2020x (Dassl) @test sum(abs.(solution.states.u[1] - [0.5, 0.0])) < 1e-4 @@ -99,7 +101,7 @@ for solver in solvers ### test with recording values (fixed step record values) tData = t_start:0.1:t_stop - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); recordValues="mass.f", saveat=tData, solver=solver, kwargs...) + solution = simulateME(fmuStruct, (t_start, t_stop); recordValues="mass.f", saveat=tData, solver=solver, kwargs...) @test length(solution.states.u) == length(tData) @test length(solution.states.t) == length(tData) @test length(solution.values.saveval) == length(tData) @@ -116,15 +118,15 @@ for solver in solvers @test abs(solution.values.saveval[1][1] - 0.75) < 1e-4 @test sum(abs.(solution.values.saveval[end][1] - -0.54435 )) < 0.015 - fmiUnload(fmu) + unloadFMU(fmu) # case 3a: ME-FMU without events, but with input signal - fmuStruct, fmu = getFMUStruct("SpringPendulumExtForce1D") + fmuStruct, fmu = getFMUStruct("SpringPendulumExtForce1D", :ME) - for inpfct in [extForce_cxt, extForce_t] + for inpfct! in [extForce_cxt!, extForce_t!] - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); inputValueReferences=["extForce"], inputFunction=inpfct, solver=solver, dtmax=dtmax_inputs, kwargs...) # dtmax to force resolution + solution = simulateME(fmuStruct, (t_start, t_stop); inputValueReferences=["extForce"], inputFunction=inpfct!, solver=solver, dtmax=dtmax_inputs, kwargs...) # dtmax to force resolution @test length(solution.states.u) > 0 @test length(solution.states.t) > 0 @@ -135,16 +137,16 @@ for solver in solvers # reference values `extForce_t` from Simulation in Dymola2020x (Dassl) @test solution.states.u[1] == [0.5, 0.0] @test sum(abs.(solution.states.u[end] - [0.613371, 0.188633])) < 0.012 - fmiUnload(fmu) + unloadFMU(fmu) # case 3b: ME-FMU without events, but with input signal (autodiff) - fmuStruct, fmu = getFMUStruct("SpringPendulumExtForce1D") + fmuStruct, fmu = getFMUStruct("SpringPendulumExtForce1D", :ME) # there are issues with AD in Julia < 1.7.0 # ToDo: Fix Linux FMU if VERSION >= v"1.7.0" && !Sys.islinux() - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); solver=solver, dtmax=dtmax_inputs, kwargs...) # dtmax to force resolution + solution = simulateME(fmuStruct, (t_start, t_stop); solver=solver, dtmax=dtmax_inputs, kwargs...) # dtmax to force resolution @test length(solution.states.u) > 0 @test length(solution.states.t) > 0 @@ -157,31 +159,29 @@ for solver in solvers @test sum(abs.(solution.states.u[end] - [0.509219, 0.314074])) < 0.01 end - fmiUnload(fmu) + unloadFMU(fmu) # case 4: ME-FMU without events, but saving value interpolation - fmuStruct, fmu = getFMUStruct("SpringPendulumExtForce1D") + fmuStruct, fmu = getFMUStruct("SpringPendulumExtForce1D", :ME) - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); saveat=tData, recordValues=:states, solver=solver, kwargs...) + solution = simulateME(fmuStruct, (t_start, t_stop); saveat=tData, recordValues=:states, solver=solver, kwargs...) @test length(solution.states.u) == length(tData) @test length(solution.states.t) == length(tData) @test length(solution.values.saveval) == length(tData) @test length(solution.values.t) == length(tData) - for i in 1:length(tData) - @test sum(abs(solution.states.t[i] - solution.states.t[i])) < 1e-6 - @test sum(abs(solution.states.u[i][1] - solution.values.saveval[i][1])) < 1e-6 - @test sum(abs(solution.states.u[i][2] - solution.values.saveval[i][2])) < 1e-6 - end + @test isapprox(solution.states.t, solution.states.t; atol=1e-6) + @test isapprox(collect(u[1] for u in solution.states.u), collect(u[1] for u in solution.values.saveval); atol=1e-6) + @test isapprox(collect(u[2] for u in solution.states.u), collect(u[2] for u in solution.values.saveval); atol=1e-6) - fmiUnload(fmu) + unloadFMU(fmu) # case 5: ME-FMU with different (random) start state - fmuStruct, fmu = getFMUStruct("SpringFrictionPendulum1D") + fmuStruct, fmu = getFMUStruct("SpringFrictionPendulum1D", :ME) - solution = fmiSimulateME(fmuStruct, (t_start, t_stop); x0=rand_x0, solver=solver, kwargs...) + solution = simulateME(fmuStruct, (t_start, t_stop); x0=rand_x0, solver=solver, kwargs...) @test length(solution.states.u) > 0 @test length(solution.states.t) > 0 @@ -189,5 +189,5 @@ for solver in solvers @test solution.states.t[end] == t_stop @test solution.states.u[1] == rand_x0 - fmiUnload(fmu) + unloadFMU(fmu) end \ No newline at end of file diff --git a/test/sim_SE.jl b/test/sim_SE.jl new file mode 100644 index 00000000..1a07977b --- /dev/null +++ b/test/sim_SE.jl @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher +# Licensed under the MIT license. See LICENSE file in the project root for details. +# + +# testing different modes for SE (scheduled execution) mode + +# [ToDo] coming soon \ No newline at end of file diff --git a/test/sim_zero_state.jl b/test/sim_zero_state.jl new file mode 100644 index 00000000..4ccd70da --- /dev/null +++ b/test/sim_zero_state.jl @@ -0,0 +1,31 @@ +# +# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher +# Licensed under the MIT license. See LICENSE file in the project root for details. +# + +using DifferentialEquations + +t_start = 0.0 +t_stop = 8.0 +solver = Tsit5() + +inputFct! = function(t, u) + u[1] = sin(t) + return nothing +end + +fmuStruct, fmu = getFMUStruct("IO", :ME) +@test fmu.isZeroState # check if zero state is identified + +solution = simulateME(fmuStruct, (t_start, t_stop); + solver=solver, + recordValues=["y_real"], # , "y_boolean", "y_integer"], # [ToDo] different types to record + inputValueReferences=["u_real"], # [ToDo] different types to set + inputFunction=inputFct!) + +@test isnothing(solution.states) +@test solution.values.t[1] == t_start +@test solution.values.t[end] == t_stop +@test isapprox(collect(u[1] for u in solution.values.saveval), sin.(solution.values.t); atol=1e-6) + +unloadFMU(fmu) \ No newline at end of file diff --git a/test/unpack.jl b/test/unpack.jl new file mode 100644 index 00000000..d007642f --- /dev/null +++ b/test/unpack.jl @@ -0,0 +1,20 @@ +# +# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher +# Licensed under the MIT license. See LICENSE file in the project root for details. +# + +# test different unpacking path options for FMUs + +pathToFMU = get_model_filename("SpringPendulum1D", ENV["EXPORTINGTOOL"], ENV["EXPORTINGVERSION"]) + +# load FMU in temporary directory +fmuStruct, myFMU = getFMUStruct(pathToFMU) +@test isfile(myFMU.zipPath) == true +@test isdir(splitext(myFMU.zipPath)[1]) == true +fmiUnload(myFMU) + +# load FMU in source directory +fmuDir = joinpath(splitpath(pathToFMU)[1:end-1]...) +fmuStruct, myFMU = getFMUStruct(pathToFMU; unpackPath=fmuDir) +@test isfile(splitext(pathToFMU)[1] * ".zip") == true +@test isdir(splitext(pathToFMU)[1]) == true \ No newline at end of file