diff --git a/.github/workflows/TestLTS.yml b/.github/workflows/TestLTS.yml new file mode 100644 index 0000000..33dc030 --- /dev/null +++ b/.github/workflows/TestLTS.yml @@ -0,0 +1,57 @@ +name: Test v1.6 (LTS) + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + paths: + - 'src/**' + - 'test/**' + - '.github/workflows/Test.yml' + - 'Project.toml' + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + julia-version: ['1.6'] + julia-arch: [x64] + os: [ubuntu-latest, windows-latest] + experimental: [false] + + steps: + # Checks-out your repository + - name: Check out repository + uses: actions/checkout@v3 + + # Set up Julia + - name: "Set up Julia" + uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.julia-version }} + arch: ${{ matrix.julia-arch }} + + # Set up cache + - name: "Set up cache" + uses: actions/cache@v3 + env: + cache-name: cache-artifacts + with: + path: ~/.julia/artifacts + key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} + restore-keys: | + ${{ runner.os }}-test-${{ env.cache-name }}- + ${{ runner.os }}-test- + ${{ runner.os }}- + + # Build package + - name: "Build package" + uses: julia-actions/julia-buildpkg@v1 + + # Run the tests + - name: "Run tests" + uses: julia-actions/julia-runtest@v1 diff --git a/.github/workflows/Test.yml b/.github/workflows/TestLatest.yml similarity index 87% rename from .github/workflows/Test.yml rename to .github/workflows/TestLatest.yml index 91a9d9b..06da0c5 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/TestLatest.yml @@ -1,4 +1,4 @@ -name: Run Tests +name: Test v1 (latest) on: workflow_dispatch: @@ -9,7 +9,7 @@ on: paths: - 'src/**' - 'test/**' - - '.github/**' + - '.github/workflows/Test.yml' - 'Project.toml' jobs: @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - julia-version: ['1.6', '1'] + julia-version: ['1'] julia-arch: [x64] os: [ubuntu-latest, windows-latest] experimental: [false] @@ -35,7 +35,7 @@ jobs: version: ${{ matrix.julia-version }} arch: ${{ matrix.julia-arch }} - # Set up cache + # Set up cache - name: "Set up cache" uses: actions/cache@v3 env: @@ -47,7 +47,7 @@ jobs: ${{ runner.os }}-test-${{ env.cache-name }}- ${{ runner.os }}-test- ${{ runner.os }}- - + # Build package - name: "Build package" uses: julia-actions/julia-buildpkg@v1 @@ -62,6 +62,8 @@ jobs: # Run codecov - name: "Run CodeCov" - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: file: lcov.info diff --git a/README.md b/README.md index 41b51d8..87f0ba5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ [![Dev Docs](https://img.shields.io/badge/docs-dev-blue.svg)](https://thummeto.github.io/FMI.jl/dev/) -[![Run Tests](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/Test.yml/badge.svg)](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/Test.yml) +[![Test (latest)](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/TestLatest.yml/badge.svg)](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/TestLatest.yml) +[![Test (LTS)](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/TestLTS.yml/badge.svg)](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/TestLTS.yml) [![Run PkgEval](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/Eval.yml/badge.svg)](https://github.com/ThummeTo/FMIImport.jl/actions/workflows/Eval.yml) [![Coverage](https://codecov.io/gh/ThummeTo/FMIImport.jl/branch/main/graph/badge.svg)](https://app.codecov.io/gh/ThummeTo/FMIImport.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) diff --git a/src/FMIImport.jl b/src/FMIImport.jl index 5e21755..f318ad2 100644 --- a/src/FMIImport.jl +++ b/src/FMIImport.jl @@ -19,7 +19,6 @@ import FMIBase.ChainRulesCore: ignore_derivatives using RelocatableFolders import FMIBase: EzXML -include("convert.jl") include("zip.jl") include("binary.jl") include("md_parse.jl") diff --git a/src/binary.jl b/src/binary.jl index 76f53b4..8f60623 100644 --- a/src/binary.jl +++ b/src/binary.jl @@ -59,6 +59,7 @@ function loadFMU( unpackPath::Union{String,Nothing} = nothing, cleanup::Bool = true, type::Union{Symbol,Nothing} = nothing, + kwargs... ) unzippedAbsPath, zipAbsPath = @@ -72,11 +73,11 @@ function loadFMU( version = root["fmiVersion"] if version == "1.0" - @assert false "FMI version 1.0 deteted, this is (currently) not supported by FMI.jl." + @assert false "FMI version 1.0 detected, this is (currently) not supported by FMI.jl." elseif version == "2.0" - return createFMU2(unzippedAbsPath, zipAbsPath; type = type) + return createFMU2(unzippedAbsPath, zipAbsPath; type = type, kwargs...) elseif version == "3.0" - return createFMU3(unzippedAbsPath, zipAbsPath; type = type) + return createFMU3(unzippedAbsPath, zipAbsPath; type = type, kwargs...) else @assert false, "Unknwon FMI version `$(version)`." end @@ -113,7 +114,7 @@ function unloadFMU(fmu::FMU2, cleanUp::Bool = true; secure_pointers::Bool = true end # the components are removed from the component list via call to fmi2FreeInstance! - @assert length(fmu.components) == 0 "fmi2Unload(...): Failure during deleting components, $(length(fmu.components)) remaining in stack." + @assert length(fmu.components) == 0 "unloadFMU(fmu::FMU2, ...): Failure during deleting components, $(length(fmu.components)) remaining in stack." if secure_pointers unloadPointers(fmu) @@ -139,7 +140,7 @@ function unloadFMU(fmu::FMU3, cleanUp::Bool = true) dlclose(fmu.libHandle) # the instances are removed from the instances list via call to fmi3FreeInstance! - @assert length(fmu.instances) == 0 "fmi3Unload(...): Failure during deleting instances, $(length(fmu.instances)) remaining in stack." + @assert length(fmu.instances) == 0 "unloadFMU(fmu::FMU3, ...): Failure during deleting instances, $(length(fmu.instances)) remaining in stack." if cleanUp try diff --git a/src/convert.jl b/src/convert.jl deleted file mode 100644 index e43892e..0000000 --- a/src/convert.jl +++ /dev/null @@ -1,207 +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. -# - -""" - getState(solution::FMUSolution, i::fmi2ValueReferenceFormat; isIndex::Bool=false) - -Returns the solution state for a given value reference `i` (for `isIndex=false`) or the i-th state (for `isIndex=true`). -""" -function getState( - solution::FMUSolution, - vrs::fmi2ValueReferenceFormat; - isIndex::Bool = false, -) - - indices = [] - - if isIndex - if length(vrs) == 1 - indices = [vrs] - else - indices = vrs - end - else - ignore_derivatives() do - vrs = prepareValueReference(solution.component.fmu, vrs) - - if !isnothing(solution.states) - for vr in vrs - found = false - for i = - 1:length( - solution.component.fmu.modelDescription.stateValueReferences, - ) - if solution.component.fmu.modelDescription.stateValueReferences[i] == - vr - push!(indices, i) - found = true - break - end - end - @assert found "Couldn't find the index for value reference `$(vr)`! This is probably because this value reference does not belong to a system state." - end - end - - end # ignore_derivatives - end - - # found something - if length(indices) == length(vrs) - - if length(vrs) == 1 # single value - return collect(u[indices[1]] for u in solution.states.u) - - else # multi value - return collect( - collect(u[indices[i]] for u in solution.states.u) for i = 1:length(indices) - ) - - end - end - - return nothing -end -export getState - -""" - getStateDerivative(solution::FMUSolution, i::fmi2ValueReferenceFormat; isIndex::Bool=false) - -Returns the solution state derivative for a given value reference `i` (for `isIndex=false`) or the i-th state (for `isIndex=true`). -""" -function getStateDerivative( - solution::FMUSolution, - vrs::fmi2ValueReferenceFormat; - isIndex::Bool = false, - order::Integer = 1, -) - indices = [] - - if isIndex - if length(vrs) == 1 - indices = [vrs] - else - indices = vrs - end - else - ignore_derivatives() do - vrs = prepareValueReference(solution.component.fmu, vrs) - - if !isnothing(solution.states) - for vr in vrs - found = false - for i = - 1:length( - solution.component.fmu.modelDescription.stateValueReferences, - ) - if solution.component.fmu.modelDescription.stateValueReferences[i] == - vr - push!(indices, i) - found = true - break - end - end - @assert found "Couldn't find the index for value reference `$(vr)`! This is probably because this value reference does not belong to a system state." - end - end - - end # ignore_derivatives - end - - # found something - if length(indices) == length(vrs) - - if length(vrs) == 1 # single value - return collect( - solution.states(t, Val{order})[indices[1]] for t in solution.states.t - ) - - else # multi value - return collect( - collect( - solution.states(t, Val{order})[indices[i]] for t in solution.states.t - ) for i = 1:length(indices) - ) - end - end - - return nothing -end -export getStateDerivative - -""" - getValue(solution::FMU2Solution, i::fmi2ValueReferenceFormat; isIndex::Bool=false) - -Returns the values for a given value reference `i` (for `isIndex=false`) or the i-th value (for `isIndex=true`). -Recording of values must be enabled. -""" -function FMIBase.getValue( - solution::FMUSolution, - vrs::fmi2ValueReferenceFormat; - isIndex::Bool = false, -) - - indices = [] - - if isIndex - if length(vrs) == 1 - indices = [vrs] - else - indices = vrs - end - else - ignore_derivatives() do - vrs = prepareValueReference(solution.component.fmu, vrs) - - if !isnothing(solution.values) - for vr in vrs - found = false - for i = 1:length(solution.valueReferences) - if solution.valueReferences[i] == vr - push!(indices, i) - found = true - break - end - end - @assert found "Couldn't find the index for value reference `$(vr)`! This is probably because this value reference does not exist for this system." - end - end - - end # ignore_derivatives - end - - # found something - if length(indices) == length(vrs) - - if length(vrs) == 1 # single value - return collect(u[indices[1]] for u in solution.values.saveval) - - else # multi value - return collect( - collect(u[indices[i]] for u in solution.values.saveval) for - i = 1:length(indices) - ) - - end - end - - return nothing -end -export getValue - -""" - getTime(solution::FMU2Solution) - -Returns the points in time of the solution `solution`. -""" -function getTime(solution::FMUSolution) - if !isnothing(solution.states) - return solution.states.t - elseif !isnothing(solution.values) - return solution.values.t - else - return nothing - end -end -export getTime