From 0a585548dc6f8b76c76735b794f14a094dca7d5f Mon Sep 17 00:00:00 2001 From: TT Date: Thu, 23 May 2024 16:13:20 +0200 Subject: [PATCH 01/10] preparation for FMIBase and FMI3 --- Project.toml | 16 +- README.md | 45 +- docs/src/assets/FMI_JL_family.pdf | Bin 110918 -> 110542 bytes docs/src/assets/FMI_JL_family.png | Bin 228800 -> 385059 bytes src/FMI.jl | 1229 +---------------------- src/FMI2/additional.jl | 168 ---- src/FMI2/comp_wraps.jl | 618 ------------ src/FMI2/sim.jl | 859 ---------------- src/FMI3/additional.jl | 175 ---- src/FMI3/comp_wraps.jl | 977 ------------------ src/FMI3/sim.jl | 1261 ----------------------- src/assertions.jl | 31 - src/check.jl | 85 -- src/deprecated.jl | 1539 ++--------------------------- src/extensions/CSV.jl | 23 - src/extensions/JLD2.jl | 32 - src/extensions/MAT.jl | 30 - src/extensions/Plots.jl | 228 ----- src/sim.jl | 475 +++++++++ test/FMI2/cs_me.jl | 33 - test/FMI2/exec_config.jl | 71 -- test/FMI2/getter_setter.jl | 85 -- test/FMI2/load_save.jl | 91 -- test/FMI2/performance.jl | 228 ----- test/FMI2/plots.jl | 37 - test/FMI2/sim_auto.jl | 49 - test/FMI2/sim_zero_state.jl | 44 - test/FMI2/state.jl | 55 -- test/FMI3/cs_me.jl | 54 - test/FMI3/exec_config.jl | 80 -- test/FMI3/getter_setter.jl | 82 -- test/FMI3/load_save.jl | 51 - test/FMI3/plots.jl | 37 - test/FMI3/sim_CS.jl | 87 -- test/FMI3/sim_ME.jl | 261 ----- test/FMI3/sim_auto.jl | 61 -- test/FMI3/state.jl | 54 - test/{FMI2 => }/eval.jl | 36 +- test/runtests.jl | 206 ++-- test/{FMI2 => }/sim_CS.jl | 34 +- test/{FMI2 => }/sim_ME.jl | 68 +- test/sim_SE.jl | 8 + test/sim_zero_state.jl | 31 + test/unpack.jl | 20 + 44 files changed, 765 insertions(+), 8889 deletions(-) delete mode 100644 src/FMI2/additional.jl delete mode 100644 src/FMI2/comp_wraps.jl delete mode 100644 src/FMI2/sim.jl delete mode 100644 src/FMI3/additional.jl delete mode 100644 src/FMI3/comp_wraps.jl delete mode 100644 src/FMI3/sim.jl delete mode 100644 src/assertions.jl delete mode 100644 src/check.jl delete mode 100644 src/extensions/CSV.jl delete mode 100644 src/extensions/JLD2.jl delete mode 100644 src/extensions/MAT.jl delete mode 100644 src/extensions/Plots.jl create mode 100644 src/sim.jl delete mode 100644 test/FMI2/cs_me.jl delete mode 100644 test/FMI2/exec_config.jl delete mode 100644 test/FMI2/getter_setter.jl delete mode 100644 test/FMI2/load_save.jl delete mode 100644 test/FMI2/performance.jl delete mode 100644 test/FMI2/plots.jl delete mode 100644 test/FMI2/sim_auto.jl delete mode 100644 test/FMI2/sim_zero_state.jl delete mode 100644 test/FMI2/state.jl delete mode 100644 test/FMI3/cs_me.jl delete mode 100644 test/FMI3/exec_config.jl delete mode 100644 test/FMI3/getter_setter.jl delete mode 100644 test/FMI3/load_save.jl delete mode 100644 test/FMI3/plots.jl delete mode 100644 test/FMI3/sim_CS.jl delete mode 100644 test/FMI3/sim_ME.jl delete mode 100644 test/FMI3/sim_auto.jl delete mode 100644 test/FMI3/state.jl rename test/{FMI2 => }/eval.jl (75%) rename test/{FMI2 => }/sim_CS.jl (50%) rename test/{FMI2 => }/sim_ME.jl (65%) create mode 100644 test/sim_SE.jl create mode 100644 test/sim_zero_state.jl create mode 100644 test/unpack.jl diff --git a/Project.toml b/Project.toml index 007b6f38..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.2" +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.12" -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 d2172f26..4644bef9 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,20 @@ [![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) +## Breaking Changes in FMI.jl v1.0.0 +If you want to migrate your project from FMI.jl < v1.0.0 to >= v1.0.0, you will face some breaking changes - but they are worth it as you will see! + +- Many functions, that are not part of the FMI-standard, had the prefix `fmi2...` or `fmi3...`. This wasn't 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. + +- Wrapper functions where removed, because that is not the Julia way. In most cases, this will not affect your code. + +- FMICore.jl and FMIImport.jl were divided into FMICore.jl, FMIImport.jl and FMIBase.jl. FMICore.jl now holds the pure standard definition (C-types and -functions), while FMIBase.jl holds everything that is needed on top of that in FMIImport.jl as well as in FMIExport.jl. + +- We tried to document every function, if you find undocumented user-level functions, please open an issue or PR. + +- Dependencies are reduced a little, to make the libraries more light-weight. + +- RAM is now auto-released, for maximum performance you can use FMUs in blocks (like file reading/writing). ## How can I use FMI.jl? 1\. Open a Julia-REPL, switch to package mode using `]`, activate your preferred environment. @@ -36,16 +50,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? @@ -56,21 +70,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 @@ -86,6 +100,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 @@ -108,7 +123,7 @@ 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. +- **#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. ## Interested in Hybrid Modelling in Julia using FMUs? See [*FMIFlux.jl*](https://github.com/ThummeTo/FMIFlux.jl). diff --git a/docs/src/assets/FMI_JL_family.pdf b/docs/src/assets/FMI_JL_family.pdf index 338448d3cdeb4ef84cc812c35fb975a27f0753f7..bf38dd10604e11a030dc70e4c000412519c87bc7 100644 GIT binary patch delta 7885 zcmb_gWmuG3yJi5XP1n#N-7`!B(jW~YDcvC`C8@rGFd!lAAP6XeN=S;7AkrNwAP5rD z-JpaA_dee_do$m4edotn|K4Ywcis1MKe5(3Z8Ic&lOzeUgibdSFX@6Hi7~7oXj$Gq zhzNr~BxezF0)dF;8X~28GX8{Ms`MsFLio~s+wKAjD@zN_ufU{l$LPs^otEO9;JqTw zUN4LbnjaUr@czi}*Yrv2*Q4nlG?Uc7pC&Q!i0&Z1v*F^p}<6zLkfb2_=OO6dV969ncQfiOgtFX3OID zvWeC<-2O<-;2*SB4G?a?Vew|}%mW3H;=HGXc~~gb$F8)Uspl_y($%Y&S+T%Ujq@c_ z)NLSm8)z&Tsh}@WupaLVZrM?=9Ji)&*^tbx53IS?_!K!~rDd>6K;1v77`bsw01Mo) zw)^nwF4+@~NZOf>_u~fd3yWv_T_#U9mxp@WhbjX750>sS^|!sZDLIvS_v2)#vm15v zOv|b;rM-OII?m$h6OK%8f_uli1XCPO`Y#ihT}lQjaKEw?16e{p4wWZ?4hEZl`x>FPZE}NcZIG4JV>nXE%X@_`<4&K&(Msfs zu}lbn+CGS+i%L#@nVazO3-OmOvnDSX4gW^<&~@sLZ=nsuL_o9IzDy?~C(r&~hR&w9 zaZe2E+vOAaJ;CkfmkDVW}!-ZHebUDXjviC znBi-K-4v&yxipiY{8YtmjR1MKxoKi=i{Wbk?-(+$CeK8kY5Zk`bxsznXs_#P%3`n+ zmda!Qm3=aJePRAb|2EGBls3Y&N6uF!eooo)O4M7%pnwSytWK4F^4b447u ze~oyarz)56)fI@)io%JwN~}l4UgA7cxO6gikSj!)LJT z*VeW&k|I~Rcu6(FwN`MwXvz#jeWX-1pS9_arj_sBuPwoaUk?Q04TYfAX-7e5;Sxhj zwhO*qivGG`_jQTVt_5B;7VjYr;osi@)_j{3H?FUv%+lvCahW!+Q}nW%th0Y!^YNxx z1X>A7}}5?e32H7?v_^Gm-nxDjs~Lv<4TBKebSmTC?DwAsjYPJx0G@*d$^`Jv7d zO;X{K#CB9JQgDz87&(W2IjHM%1)|S%`~3q#U+^kz+oDV0mMKRAaX8t1@HN|CmX?$x zS70dwo^_T8qtj&Pz*YwJ>03}B@Xi!CX5cv+b*b|Q(Rm#!NlO-!H)VYxghgmz+1x1V z6HNlydr!#JF2^u|!bn8HV~XSSo<*5B|0LR~-qA)?H*U=hj!fOFvW$UY19KF2A{z7c zst@OPHxo5gBf!})?p&Kp)^<~IO=@#L9!Z)A>l>~OKC<_snkIKes!its`cLmT?&(Z*iCa}@<<)Zbmqt=MLAWw z(rfbT22b`wS6UU9iFT6SRL__*WEjoxW3#VVMv!^f|D+@-3eCWA@R*l^d8 zoz!Ws2yD=B*vt7vX#iR;R9aro@CrH$rZc6fZ1j7f^(K=xYw8w8=QEf;C6$U0j`%us z?pO3q(t_e^c`xd7tKIqin5}BWnLb_UF5?y^mRfpxPvM_<*M^jjUVX^ibap9^GO@W zcLVj!Dnp#FZ*p@S!6<3i`Kpalqqi5UCZ@6#Z0@q1deua`ynp?1bndQxb$;NF_afG` zH8Zqca)(i)!0>VFoM=GahP*vPq00|ScFp+74u)Y$?#jei)u4X$28$p}-O=7YXG}i$ z%jXl))v5J;I@!P``tQ&E6KMMqbv!nvc)x(3gjx(I|77Ya(_1I!Hdr|;mB!W57Xogq ze9JG=T(fdMRz?1!xj?e zbaMfxvJXMF&qh~61bfR(7|txLE*2G3&&lJyVm%CP3+HZi{tI=%Zo?+l%JJU&2_&G9lSJd zyi<4B4)A@}wjtB&e-)%y|La1Z(1TdgX~q-g(cuFe%pFsl6%^o~SGm>BvYZ^=WTm@B z&PwC{)7jX2GuxEPdxly5V3{shUNiUWP%@J|pwYjhaF;mufP1||d&1h1Pw}YH7Hs>r zFxdZ>*ePX6LJjNGN%!)zFN5=JWhVDV;4Sb*eIVfIQB}^?dSenc&9qe)IvCMwEK78! z6PvcU{fH&|ZObaI4$c9Q_>x$2bB_|rgMkL(Geq6k=~k_LV*;4qx6KH z_RFOuW#X=O+cyk)+&g$zMyFnX6YbAcHXHS>r|6Sii|I>q6CEy0cCGnf{){_Y_S;GU z@KJkEtx(b&b;}d6!QrQFVKQQIMZFxBm!HTrK={7?3Ayi;^1)oQOIZxgNNi;?%Zv2r za_TNGpTs)}rCv>iR^vw2?d(?v#^SQgBO5J~REF3uTnvBI6zfQ^-?=P{y`RLcD^z4o zY8DXH6@f(#LM2?wI$aUe3B%%f-xZzJfCv3=isgfzykyQuv95zkM&05=bI1mIXSVHf zk}(r>hTE%KC9C|*Thit`$&oWQ5qy*zGc=b7R-`J~Gh(uEb+0{mytYjyaLr)n0~$8h zR{dg`!_Xs?sFFyjIKEcG4OKpis31}rty4#Ken+OUL8!~$=*o~dE~d15);lO;07bD_ znTC_LC^f@zGe;&&l5N{dHbQ=?7}Jmby##_1!9GQ7<)v9YrVD!B$vgHURG`m1Je*4v zeZtq<__kz{$K%{)-0BnSGEwARlDDE^VmCV#A`zDh89_l7F4cqv+de&qtF6ZMr1{oF zq1qj4Nt9W+MxHxQF^>0{MH4IL0HtNNS8Mgs?@7XVK4|1H%uq@oEn<@1H?YQAvzFF$ z9d_MYdZ2T2kw>F2Jd^*$;7(Ut2$I^Xh>>qEb=y?_ORzLV@kJkwT6I%>-%dTtLRR&M z%9!&_nb4Dj>$?mvuq~Hghw+E5t9GQ z*uAgatWJbxvbG(1f6%-;c&uSudrk1YuHlo1l?RzE5BjN-^{IDDuE<(sf}S8OW(&R< z5HRo_MZLaeqpYE|y)FkKM=+1y6Bz^MFY*T5%`jx+Fc8QJa2p%*_6yH4|^Qrynun0+Zg= zx(CwU4^0#w%CpomPgEDM)-v;Hu8j08AnKcPe>nR|Gp;&F4WEUJPSv(q&Ng0h))=EjLr##M^Z?4IM=KOq z?pjZlLn~yxRZtk4u9=f*=D`aQHlwuvL)GG?#{-<)ve}hzh90s5V?dmA`r^Es2TX&L zTyk2V_@k_jFm|Nlqnbm8S@?~yB3t=%qCOcq%BYsF1q_Z&xXMa*hu+PIO4SuF2w0an zJCq`H#7mUqhey3_#!dA;2OvD>a6&OF%zRt8*TH5;#%ZiMu!~F@~skL7cIco?(@% zws*VK2KF|Ro$H~05qGxF6oc5EP~<9ODp+CQ^k^-Ud0L8lko0Wl5$iiFC`Q&IT(`8e5mQc(mx$urZw`4vsu0A2*9%0iMfs72_7 zDH!iOjq$k8LtPqaOXJ=oqwXo@#rX8(;3!TNBdOK-=2q#C^o@*ZFDwm4N^3f`^l(I3 zl+i>ZvWZNMUyj@=XD;HcR-llE`Lvjl9=W-w9S@&2)w|1@O(x?2GAD;VkFl7TlkADF zFsG|PS9JSfJgL}yg{OJgC}JJus+5GQBwGA;Yq>AC67oI^W4uQ1Gs^K9Cu1waki0r7v&{FEE%Ev42Y;^M&~tDPgp|PB{+0%k(a!>%VmDl6#%|w34Q9*{lyZ)?j zwuvBZhf9og;c(GanFROOHKfw%;KZT<$9p+iuFVfsRoJ_G-aSlz%qeOX@L+Es6-0CU zH7AT6BAfLT6dy^%kFDGY*EHztA)#yhBg|O9+%9NPFg)T@7(i*?sWcEa#;QtjvCCYE z>*1b&)*^89w%XoHq&P-xE2#4Jw}_dO+B-Wq;Tv}^VeJRkvo^-`S4u^SA1Mcffpcyj ztnU@V%6v#n*2>6mTy=p(Re<7YepNT>0OSa+3Oi*8c?gzMJ09Y;Rh$xuec=_7akHs^ z-(m;$0O{bm0hGUft9cvYR+;To$*!_Dp%F=fH;>^9C@*u7m^`n1A`-QCI?pPjum%FPt)SJLm>w6z1sIp6Ye=>WaZ z*Uki#J}pVi{r2*wP>~+dx7QFl5uselRfyot40#F3y{f2hjr(CdMC!$)4c4B-F%ms- z6dx)A6i3=ij2O1kZ~1cpF$0Hu!p~BZ%zdyXw~~hatPM`F>PxR)EK&8QR1D+hJskbk z5fA(7+pfsC=-eHCyj$6$V^mwI6+6szz@_p*VSs6v}dOW{`F(nR+V06pY|gOmSz7T4~LME;)an|ey@RyiTInkJKtNW#&>pUmAlp7 zwvPO~F~adiL2l~T(-Uvwl8iZ}cKiBT8q)H5t|*CsJ!kH9vOT$D{WgN>&xWM z>|Wt7(ChKd3%>^-5fp*0ApFU4HUu#h97hK@5TuGR8KgzT0GEIuB&1941Gg_n~P+ zNaxr)lU2e9)s#o70*qP|aa!un5?zHEwNlle(Nn~QX%I)KJ7^1U&L72CjN9n>^wn=n z_)<1oDkw1f_CsS?E^mq#bzejg`j+x-lc?Q&UTSW~u|H+SNcjONM;-!*d5}eN&#O)I zKKW23ECX)kog#6e*J%tD){I01GD=0+>loqq+us=hsZTSh{_pZ0U$yV+PJxoCKq&bj1SgxO5H_)2@#3}-#8HuG z4J^M#xK77CMvVx#MkGfER=guZu7i}F@g66K0i~J&nVv8RoT9>-5(bu=!cvgkqd7Jp zH#VT5dxd2qQFJ3zQLK=OJ3lsRyret>9Vzy-;)=d1I43&GG#KlIMb zUzX}Sn3dB(=y$#T5$NOOOho}XOF9gfl>_nwkO(vn!BJ2sz6}Y-vteMc z^ELz&g>QqQ@GuZ?1m^dkw83YP)R?olJ|B^A%EuX9|Y0(1kn(D`O(mS z$p1V45C~ctUw$+Ug2x&SL*vPhh9mLFpb-c>Rncb>o>u{lLIHRYV<7mlo=s%D++m>j zQe$9nd_OoG9|Q5Pv;+TJ!5Acd-Z3cr_Qat74M7a*JTMdjg`Mx5GaKfg3ZCf?g}~6~ zi{>m|DCl|l&ukccGH8@Ea4sj%Gd6gRPzVN(%vl}bk%q$2 z=Q{!lMc`FG6nfSs|BVa$YwAJI+8s|qCpY5Z1%O2ZKU0{(AY z00NapK=FX35$N;4(ikZGe8eym3~%b4l@{iF%OcN6p94Ni92_dm!|>Jjri1Pj5D@87T0$vF2Lx%P8I%qIL0Saq5(K2B8;*h~jdWZ* zzk8m0j&q*p-aqdCV`lGfeQUk%dcRnE4=fONEfdB`;9A?nOKAd-@lnhGROPD!03H&K zO3cJ%N87_X-s8yyihJQQlD}*h#eMrN*s`z8#LU!0Z3eyI{&DL3pg~>s3s2x1_Wp;c zFt!AVFvgZskISXGFKMSsQ|@%n+dnVme*6mOy`)wv<(XRWddNcnVF{k zmqO%QGFh2NOXrQPHe2%3Mmw7&qlq#ZnPg%d0qDA;M@J{$qi!?@9Q!|9@P|nHHT&Ox z*fW9Wx}Q3dzG!z{`kRE(u6=dXe%Sr;J&AIOcXG{Td>7H@o*;rxe*538S3PO+V!OQ< zSuLh5R+YtMJ&xP`&th^~;v@Ml^6OHbk|wcqK~;tC4+O_%f*-KV8Cx@5lzR0$8X)}9 zzPsqwVuNa$a%uDV0pHFj8PoaZ8w2y^88YZf(x!Sc1>1 zM&6{DKGN8z%lNqieTs3qSYzVY>Va3l^l>!(J;2H8F@nl+S;2_Z)Qe&`d~lpWjf&Hgx>+?MfML@ANp z4t|6q1-7bTaEFmk8ah;V{r;*^%qq}6i0!R!8YX-vb=up*E`4AwjPFxjGH_$A^Axy9 z#gd|zRy~M?z`g2X)R|d`aGj~%FrO-YFM3;CkVT$}_uj2l-RM>o;OnA9_vGzY=w{g& zQTTJ1rBa?$JsrtDqs4yF?MUtD>&=VN-ezB}#m075x|zLkS-?oDXLNd79WPR6H>y8! zp!*aQ^dl9YD2otSvmIS*SVwZ8`eSu;HH5iiVph8Xs+n`p0XMQ67GFm4OSu|~c(=X$^LbIZo6KTiT~`F5MxH)BqM;+~S^qA7RzKSc_S#)kx7ZG-?^l%(?PH6;>{U{ zDA_VTeM>lV&8&6knKo*`fh^IK?xrrmf_84}9Dzg#J$jJ^vKNN2Szf9*$BR8$+s zdMHh{Gp6KuFM5Qm+`C;sQk1Zq^3!R1xFfPPji97rZ1xLRh?NrS_eTC!(o?;`T>13z z3hGBQmVrOn#&KjOo)xE&F26*7S`+X0N{Fi!nQT@1c0+BDEm%`ehEDP6&==DC&p3*- z>W;pCJ}TnLZI2S8@TBY{EeCEZE@h82zlx&oO}yjx?iCZ8f+B9crj9o=?b;2aJX!<# zy^iHNShBDOVMsPG=lhPz%NtAW!u8j8v)S0*3Q|ZvaQQ^>%Fm{Guj7~MT=0iO~J6ss@)^fM!zFrRfbwhMj7+@1&e@s_IdvL zHB!uKp$p1u;>1;+r5et%qYk*x#n+k%4eyGIdlr5n8MU^D;Yxi$l;Y0Up5Dhj-YqJB zxjEw7(}1VE9~K>+YYpboqK`>6d||I|322hxUPK0H2stlQ_aj6Kc&+sCpRaZ$Y}lo> zaN<&XDkx@3N1pt8M9V}Ji9Lmy_J-+ANBaNRlnAoI zJbM*xG+oWG|B)<(lRJ>A1ZuM(-Bi?{UUI>0e3Max{qxBQYm`mN)={owQEz*&zkX`t z*P{@RQhKlTco}edZiRJZ6r3v6KuX^3g`1Jv%e?(Lun*URhiFR&0s#a1Ct;uQEL{{O zNwgVv2As(+6f9-Bw<|zT74%;VXtuBuUY;GVk8X#R=u4h@CJ&SysI+T-$lC7R1bny# zHekd36darC+@EDp>Sl1V$qla*AGDiP^*vJ_aczu`miHM{ZZ`2jHJpAq5E0`Qt9*S* zIoUS1!R@sjf#onrqWSx4vkRdBXRC!qxcZ!X@QU(ob%x|C%6SjE}xhJ3s9TM>-h8}^Y zkur_O`U&ABiN-@K8H$TO`;Xc$-BdeP4Q@~~l)3Dzh;Y?h>=L$|9a5k4GAcodTU2X* zo;%P#Y!$scCjObpb8WL&WiyXmcMD|uB!Q<^rM!J`9nbe%=IY7xU7l;#S@7K_WYO9Q z*%ZE6+NWswvq3w2SJMo?#|P#P&%5nUc#a)n+t|fODeO;t^&e?Tm$T?zh`5cMs;nLJ zL{F7v3OwlJgo#}c&q?EcKBatIi@ zZQ)BS0GPK<#zdQ)Z&BRr$@kHprK2^QG_8RQVVuz65u&aU0G_maUW86P1xyyTovKsD zH4sY;_=i?M_=oJfSB?^kULQI|!tYPZdpzdYlxG`-clxj{X9T?^T5cqNG^Ole$FUVu z=cHg-OFhRd;K$)ILsjdn_?XCx(^hess@hiew0I6s8!|ar1mm6FqMw+(Z};|kzG9w) zmmk`W=e%;JArE4{;kUGG{w&HU$e?)IfN>(t!gnt+Mx0!?QP*75Cpg2RvGKh>T7P%@ z%w>{McG-hEK1oo@m)6IrYrZMur+L-*Ad6hU?G$*)9D_-vmCJ{Vw}w@dYEpHH5zlKh zO7EY;`MV3*9Ls###b!}@s!TKSUlR-rO7_qXy-r`q$h>(P@af`Y$^3h2`i)_Cn!VkQ zD4yaYg00>=$ti5&V!bm73I+vUi3-|ENvWAz8$Y?6dU6WcjDlpmU2m-V`MvJVln33% z-F~4wvsgNRghylCnB|_)xA@{f$?lUiw^106ufreFWf93|^ajaV0(4Chef6&&+!u8l zLNhz}#J|mLbX#rEGIOdcNt3Q~c4L)U5SgLXpyMJvk>KAA#;#+c}^Fbd!mdB@Q>^wLLK1ol4c2ptBh3 zYaUU}6`V;;*5>!L{Si5)W$yYx-zlf$+q~Vt2zT;YO%Y|6zfeaHOn)^_fSj#}of!P? zv$I-e)kKc%LA(IbjA5EzI-wrkfLvLVT6dsiN!3p2VUs}OgNd2vt}P(n)EH7j>qB&L zJ~)ORfvquNR#TnhK8KYn$3qfk8{Lz{q~d;Y zk1(epd0y}qG`}opdR`dq%0WyT&4U)_92mM+T_f;pE6r2k4xdvQcpPQv%VlvxoOndY zil5$DlVMtKY3ib_Quhr^ffbQ7Ry)8#7U%l&6&`h?&b!q3RYG*({& za>6>Ij_V{00SwwwHF}ofLu3au9&a9BQ)(LGByi;vRJ1vpVzE@MkRvF>Kzh;m6$hZo zZdv>7c@ZA{Gz#m;87F5;%Z)jON9*dudbcQ|%XLglGXUu|#(xygGvG3EhDDbeKUPy! zA9q(y1HgL&o32gah_ciYpri~-uKAh1e8TdRtI zw?5)#&{lp?DY^2V3R3lJbi~;b4Nj>h3vFXO#aGWaf{pPhv3k{Nbhztp~z8@U=+? zYBIAv7t^t;-*~5iqKsr`-w?I&fi>gM6+_t7$tQ0T>_oX8YdOcFJffmeldfYMA`%Sr zP*$jOkW&p^m~J_W(Je)@c6hdH?vo8V+w?{&g(|>(kiwBv6gk2MQy7vK9dG$55ZK*R zvLkhvFPt`4s6j05wL8%EmIBp`^qXNppL0=bgD|=HxDcOk5VsZ;zhad=J8v!(|Mi{X zl4whf+;a~ne2~E8T#s_fJJBf`N}tb_xx{+o=OC9!axu|5XdjcA*ShSt!U+8BcLb_ z27>?TQGL1l7(j*uizz#}xqEORfZ#++H&!$V3Pwmvlaso8xY<}alaqRdi-e&^(TK!3*Ae1=z!hF-;Z0s_gCB<$Fhmz|<(#O6MFN0Fi_Sl1-Z>P1c zuH*d$0SAZcf)%8E#ZPG)t5e6DAx^rU^FK89xP{E3)%cOo2^1pK=eaCLimOvi#CET& zx0)_?5)Vyp5ox*7Zmu|aV-9F9XgycK$+}>_+aA#+S?aCJs$Z{@`HwlF+vkIAOrNRY z?kYVh+)WhqCnh?sUpGVc$~V)Fn66QR*RMm*Y-&x-wgQTBeWJ=c1^J70SgwE0a?ACl zqD4|t;@XpD(i4# z0>Cd=x*_oDa9UfZe!>fmF7(iLkYX_uf3nn4RI}JgmZ;GIA33-gloyn#TvM|Luzpd3<`Gu>cWWiSHUCG=8D`^>$L54xX z3U5>1V6zbChBu7346$#lD}L0%_@6rx6y`Wabj%ED6QIn?)4qAw-?~wvEM&KmpKJ)H z>FYWyO<(i)dA+EQKs_Hw?@gc>xY-R?F+>@F?a zfBV1}6013Cdm~NX+oJS%g%2-FpB48@;n|Dos0Iy`aMz5?x$I3eql+BLzM$2ZCTkVt z*$ZcNHVvdx zX>Dti4QU&^@4GZ)DMrUMC(RE!K-c>il~I@eN2Yv|lgj8*<|A?cu2!O5fA7a{NBvcn zAidH%j>z`Q%P)k@DraQOI@;aCD=L>blT=HDR{cA^eb_s$-J zP|@u4NV~>2g6R>~S4H&H??287KLa9>4an3~CU#S{TdKry#AsP|=7(|kj6^H)Y_~df z?pa#G1M8^n_x5c?*&(wed-l@zG7lwDUC2Dscj;62KMAsKYt&_u3~Dd&evkm5PupvS zStb^zh~z-lXK?uB7;j|#8nF0P4=E`H~pz{Zr+Rl>KsLc zTQBnZ(+^X{(VX*4vn;YdTw{7sDV@zR@N!2feld|Ib}?#=DX^AHEya#5?0+p5eEQiy$ z7^b`}M+*%m7oiHdODrc5l0%+L6~xrZ2@q73C$i?mb65+N^pK~hU!*Y&l>n@T3EvJZ z8N!>$W-L>fWTBJjl9Nx>i%E9@dqPW9aEn zgek}YT*pO#FkLwSXEY1}<^cY>I9$j{|GWW0;b0iH4S~e6A)$!hZLq84!m@!;SQsz} z0`kib{dZs(6b8kb41-{ifx$s=EI&938yJC28is_S{x|d$VQ?%3;RrMWYsc`b^28#8LSYd^0Fi&+$)BVVAOyA_7zX-%Jp=^y zA3yZp;*NmAu_Q#m;8-dk5MV5V2*ke-L}AO1ywdvbWd7723Br~i2?k@aMqahAzfb

aTL w-(NTu|1UUVx7}>KIR3M|n4zwXt)7ST)#I;CRh9#2Nv~QsIVmr%lD6`H0kK#Yh5!Hn diff --git a/docs/src/assets/FMI_JL_family.png b/docs/src/assets/FMI_JL_family.png index 5e81fd6e88cefb662b342d93c0efc82240f74e6a..e4e58a13421df2930e4453d2da796513a458fc97 100644 GIT binary patch literal 385059 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 z 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≤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

exEabrArQfiv0ai$zvPMwHA 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 Nj5d>__q-=md?!LI$;Oyq;)ZC&2L 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 literal 228800 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

F$G#wRAA1k97+OwFpUO7eB9+q>M^zeXnQLvx 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 tStart && c.eventInfo.nextEventTime <= tStop - return c.eventInfo.nextEventTime - else - # the time event is outside the simulation range! - @debug "Next time event @$(c.eventInfo.nextEventTime)s is outside simulation time range ($(tStart), $(tStop)), skipping." - return nothing - end - else - return nothing - end - -end - -# Returns the event indicators for an FMU. -function condition(c::FMU2Component, out, x, t, integrator, inputFunction) - - @assert c.state == fmi2ComponentStateContinuousTimeMode "condition(...):\n" * ERR_MSG_CONT_TIME_MODE - - indicators!(c, out, x, t, inputFunction) - - return nothing -end - -# Handles the upcoming events. -# Sets a new state for the solver from the FMU (if needed). -function affectFMU!(c::FMU2Component, integrator, idx, inputFunction, solution::FMU2Solution) - - @assert c.state == fmi2ComponentStateContinuousTimeMode "affectFMU!(...):\n" * ERR_MSG_CONT_TIME_MODE - - c.solution.evals_affect += 1 - - # there are fx-evaluations before the event is handled, reset the FMU state to the current integrator step - fx_set(c, integrator.u, integrator.t, inputFunction; force=true) - - fmi2EnterEventMode(c) - - # Event found - handle it - handleEvents(c) - - left_x = nothing - right_x = nothing - - if c.eventInfo.valuesOfContinuousStatesChanged == fmi2True - left_x = integrator.u - right_x = fmi2GetContinuousStates(c) - @debug "affectFMU!(...): Handled event at t=$(integrator.t), new state is $(right_x)" - integrator.u = right_x - - u_modified!(integrator, true) - else - u_modified!(integrator, false) - @debug "affectFMU!(...): Handled event at t=$(integrator.t), no new state." - end - - if c.eventInfo.nominalsOfContinuousStatesChanged == fmi2True - x_nom = fmi2GetNominalsOfContinuousStates(c) - end - - ignore_derivatives() do - if idx != -1 # -1 no event, 0, time event, >=1 state event with indicator - e = FMU2Event(integrator.t, UInt64(idx), left_x, right_x) - push!(solution.events, e) - end - end - - #fmi2EnterContinuousTimeMode(c) -end - -# This callback is called every time the integrator finishes an (accpeted) integration step. -function stepCompleted(c::FMU2Component, x, t, integrator, inputFunction, progressMeter, tStart, tStop, solution::FMU2Solution) - - @assert c.state == fmi2ComponentStateContinuousTimeMode "stepCompleted(...):\n" * ERR_MSG_CONT_TIME_MODE - - c.solution.evals_stepcompleted += 1 - - if progressMeter !== nothing - stat = 1000.0*(t-tStart)/(tStop-tStart) - if !isnan(stat) - stat = floor(Integer, stat) - ProgressMeter.update!(progressMeter, stat) - end - end - - (status, enterEventMode, terminateSimulation) = fmi2CompletedIntegratorStep(c, fmi2True) - - if terminateSimulation == fmi2True - @error "stepCompleted(...): FMU requested termination!" - end - - if enterEventMode == fmi2True - affectFMU!(c, integrator, -1, inputFunction, solution) - else - if !isnothing(inputFunction) - u = eval!(inputFunction, c, x, t) - u_refs = inputFunction.vrs - fmi2SetReal(c, u_refs, u) - end - end -end - -# save FMU values -function saveValues(c::FMU2Component, recordValues, x, t, integrator, inputFunction) - - @assert c.state == fmi2ComponentStateContinuousTimeMode "saveValues(...):\n" * ERR_MSG_CONT_TIME_MODE - - c.solution.evals_savevalues += 1 - - fx_set(c, x, t, inputFunction) - - # ToDo: Replace by inplace statement! - return (fmiGet(c, recordValues)...,) -end - -function saveEventIndicators(c::FMU2Component, recordEventIndicators, x, t, integrator, inputFunction) - - @assert c.state == fmi2ComponentStateContinuousTimeMode "saveEventIndicators(...):\n" * ERR_MSG_CONT_TIME_MODE - - c.solution.evals_saveeventindicators += 1 - - out = zeros(fmi2Real, c.fmu.modelDescription.numberOfEventIndicators) - indicators!(c, out, x, t, inputFunction) - - # ToDo: Replace by inplace statement! - return (out[recordEventIndicators]...,) -end - -function saveEigenvalues(c::FMU2Component, x, t, integrator, inputFunction) - - @assert c.state == fmi2ComponentStateContinuousTimeMode "saveEigenvalues(...):\n" * ERR_MSG_CONT_TIME_MODE - - c.solution.evals_saveeigenvalues += 1 - - fx_set(c, x, t, inputFunction) - - # ToDo: Replace this by an directional derivative call! - A = ReverseDiff.jacobian(_x -> FMI.fx(c, _x, [], t), x) - eigs = eigvals(A) - - vals = [] - for e in eigs - push!(vals, real(e)) - push!(vals, imag(e)) - end - - # ToDo: Replace by inplace statement! - return (vals...,) -end - -function fx(c::FMU2Component, - dx::AbstractArray{<:Real}, - x::AbstractArray{<:Real}, - p::Tuple, - t::Real, - inputFunction::Union{Nothing, FMU2InputFunction}) - - c.solution.evals_fx_inplace += 1 - - u = EMPTY_fmi2Real - u_refs = EMPTY_fmi2ValueReference - if !isnothing(inputFunction) - u = eval!(inputFunction, c, x, t) - u_refs = inputFunction.vrs - end - - # for zero state FMUs, don't request a `dx` - if c.fmu.isZeroState - c(;x=x, u=u, u_refs=u_refs, t=t) - else - c(;dx=dx, x=x, u=u, u_refs=u_refs, t=t) - end - - return nothing -end - -function fx(c::FMU2Component, - x::AbstractArray{<:Real}, - p::Tuple, - t::Real, - inputFunction::Union{Nothing, FMU2InputFunction}) - - c.solution.evals_fx_outofplace += 1 - - dx = zeros(fmi2Real, length(x)) - - fx(c, dx, x, p, t) - c.solution.evals_fx_inplace -= 1 # correct statisitics, because fx-call above -> this was in fact an out-of-place evaluation - - return dx -end - -function fx_set(c::FMU2Component, - x::AbstractArray{<:Real}, - t::Real, - inputFunction::Union{Nothing, FMU2InputFunction}; force::Bool=false) - - u = EMPTY_fmi2Real - u_refs = EMPTY_fmi2ValueReference - if !isnothing(inputFunction) - u = eval!(inputFunction, c, x, t) - u_refs = inputFunction.vrs - end - - oldForce = c.force - c.force = force - c(;x=x, u=u, u_refs=u_refs, t=t) - c.force = oldForce - - return nothing -end - -function indicators!(c::FMU2Component, - ec, - x::AbstractArray{<:Real}, - t::Real, - inputFunction::Union{Nothing, FMU2InputFunction}) - - c.solution.evals_condition += 1 - - u = EMPTY_fmi2Real - u_refs = EMPTY_fmi2ValueReference - if !isnothing(inputFunction) - u = eval!(inputFunction, c, x, t) - u_refs = inputFunction.vrs - end - - c(;x=x, u=u, u_refs=u_refs, t=t, ec=ec) - - return nothing -end - -""" - fmi2SimulateME(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) - -Wrapper for `fmi2SimulateME(fmu::FMU2, c::Union{FMU2Component, Nothing}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...)` without a provided FMU2. -(FMU2 `fmu` is taken from `c`) -""" -function fmi2SimulateME(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) - fmi2SimulateME(c.fmu, c, tspan; kwargs...) -end - -# sets up the ODEProblem for simulating a ME-FMU -function setupODEProblem(c::FMU2Component, x0::AbstractArray{fmi2Real}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; p=(), customFx=nothing, inputFunction::Union{FMU2InputFunction, Nothing}=nothing) - - if customFx === nothing - customFx = (dx, x, p, t) -> fx(c, dx, x, p, t, inputFunction) - end - - ff = ODEFunction{true}(customFx, - tgrad=nothing) - c.problem = ODEProblem{true}(ff, x0, tspan, p) - - return c.problem -end - -""" - fmi2SimulateME(fmu::FMU2, - c::Union{FMU2Component, Nothing}=nothing, - tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; - [tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - solver = nothing, - customFx = nothing, - recordValues::fmi2ValueReferenceFormat = nothing, - recordEventIndicators::Union{AbstractArray{<:Integer, 1}, UnitRange{<:Integer}, Nothing} = nothing, - recordEigenvalues::Bool=false, - 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, - callbacksBefore = [], - callbacksAfter = [], - showProgress::Bool = true, - kwargs...]) - -Simulate ME-FMU for the given simulation time interval. - -State- and Time-Events are handled correctly. - -# Arguments -- `fmu::FMU2`: Mutable struct representing a FMU and all it instantiated instances. -- `c::Union{FMU2Component, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. -- `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)) - -- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) -- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) -- `solver = nothing`: Any Julia-supported ODE-solver (default = nothing: use DifferentialEquations.jl default solver) -- `customFx`: [deprecated] custom state derivative function ẋ=f(x,t) -- `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::Union{Bool, Nothing} = nothing`: call fmi2SetupExperiment, fmi2EnterInitializationMode and fmi2ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `reset::Union{Bool, Nothing} = nothing`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `instantiate::Union{Bool, Nothing} = nothing`: call fmi2Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi2FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `terminate::Union{Bool, Nothing} = nothing`: 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. - - ## Pattern [`c`: current component, `u`: current state ,`t`: current time, returning array of values to be passed to `fmi2SetReal(..., inputValueReferences, inputFunction(...))`]: - - `inputFunction(t::fmi2Real)` - - `inputFunction(c::FMU2Component, t::fmi2Real)` - - `inputFunction(c::FMU2Component, u::Union{AbstractArray{fmi2Real,1}, Nothing})` - - `inputFunction(u::Union{AbstractArray{fmi2Real,1}, Nothing}, t::fmi2Real)` - - `inputFunction(c::FMU2Component, u::Union{AbstractArray{fmi2Real,1}, Nothing}, t::fmi2Real)` - -- `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 -- `dtmax::Union{Real, Nothing} = nothing`: sets the maximum stepszie for the solver (default = nothing: use `(Simulation-time-span-length)/100.0`) -- `callbacksBefore = [], callbacksAfter = []`: functions that are to be called before and after internal time-event-, state-event- and step-event-callbacks are called -- `showProgress::Bool = true`: print simulation progressmeter in REPL -- `kwargs...`: keyword arguments that get passed onto the solvers solve call - -# Returns: -- If keyword `recordValues` has value `nothing`, a struct of type `ODESolution`. -- If keyword `recordValues` is set, a tuple of type `(ODESolution, DiffEqCallbacks.SavedValues)`. - -See also [`fmi2Simulate`](@ref), [`fmi2SimulateCS`](@ref). -""" -function fmi2SimulateME(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - solver = nothing, - customFx = nothing, - recordValues::fmi2ValueReferenceFormat = nothing, - recordEventIndicators::Union{AbstractArray{<:Integer, 1}, UnitRange{<:Integer}, Nothing} = nothing, - recordEigenvalues::Bool=false, - 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, - callbacksBefore = [], - callbacksAfter = [], - showProgress::Bool = true, - kwargs...) - - @assert fmi2IsModelExchange(fmu) "fmi2SimulateME(...): This function supports Model Excahnge FMUs only." - #@assert fmu.type == fmi2TypeModelExchange "fmi2SimulateME(...): This FMU supports Model Exchange, but was instantiated in CS mode. Use `fmiLoad(...; type=:ME)`." - - recordValues = prepareValueReference(fmu, recordValues) - inputValueReferences = prepareValueReference(fmu, inputValueReferences) - - savingValues = (length(recordValues) > 0) - savingEventIndicators = !isnothing(recordEventIndicators) - hasInputs = (length(inputValueReferences) > 0) - hasParameters = (parameters !== nothing) - hasStartState = (x0 !== nothing) - - t_start, t_stop = (tspan == nothing ? (nothing, nothing) : tspan) - - cbs = [] - - for cb in callbacksBefore - push!(cbs, cb) - end - - if t_start === nothing - t_start = fmi2GetDefaultStartTime(fmu.modelDescription) - - if t_start === nothing - t_start = 0.0 - @info "No `t_start` choosen, no `t_start` availabel in the FMU, auto-picked `t_start=0.0`." - end - end - - if t_stop === nothing - t_stop = fmi2GetDefaultStopTime(fmu.modelDescription) - - if t_stop === nothing - t_stop = 1.0 - @warn "No `t_stop` choosen, no `t_stop` availabel in the FMU, auto-picked `t_stop=1.0`." - end - end - - if tolerance === nothing - tolerance = fmi2GetDefaultTolerance(fmu.modelDescription) - # if no tolerance is given, pick auto-setting from DifferentialEquations.jl - end - - if dt === nothing - dt = fmi2GetDefaultStepSize(fmu.modelDescription) - # if no dt is given, pick auto-setting from DifferentialEquations.jl - end - - if dtmax === nothing - dtmax = (t_stop-t_start)/100.0 - end - - # input function handling - _inputFunction = nothing - if inputFunction != nothing - _inputFunction = FMU2InputFunction(inputFunction, inputValueReferences) - end - - # argument `tolerance=nothing` here, because ME-FMUs doesn't support tolerance control (no solver included) - # tolerance for the solver is set-up later in this function - inputs = nothing - if hasInputs - inputValues = eval!(_inputFunction, nothing, nothing, t_start) - inputs = Dict(inputValueReferences .=> inputValues) - end - - c, x0 = prepareSolveFMU(fmu, c, fmi2TypeModelExchange, instantiate, freeInstance, terminate, reset, setup, parameters, t_start, t_stop, nothing; x0=x0, inputs=inputs, handleEvents=FMI.handleEvents) - fmusol = c.solution - - # Zero state FMU: add dummy state - if c.fmu.isZeroState - x0 = [0.0] - 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) - - c.fmu.hasStateEvents = (c.fmu.modelDescription.numberOfEventIndicators > 0) - c.fmu.hasTimeEvents = (c.eventInfo.nextEventTimeDefined == fmi2True) - - setupODEProblem(c, x0, (t_start, t_stop); customFx=customFx, inputFunction=_inputFunction) - - 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 - - # callback functions - - if c.fmu.hasTimeEvents && c.fmu.executionConfig.handleTimeEvents - timeEventCb = IterativeCallback((integrator) -> time_choice(c, integrator, t_start, t_stop), - (integrator) -> affectFMU!(c, integrator, 0, _inputFunction, fmusol), Float64; - initial_affect = (c.eventInfo.nextEventTime == t_start), - save_positions=(false,false)) - push!(cbs, timeEventCb) - end - - if c.fmu.hasStateEvents && c.fmu.executionConfig.handleStateEvents - - eventCb = VectorContinuousCallback((out, x, t, integrator) -> condition(c, out, x, t, integrator, _inputFunction), - (integrator, idx) -> affectFMU!(c, integrator, idx, _inputFunction, fmusol), - Int64(c.fmu.modelDescription.numberOfEventIndicators); - rootfind = RightRootFind, - save_positions=(false,false), - interp_points=fmu.executionConfig.rootSearchInterpolationPoints) - push!(cbs, eventCb) - end - - # use step callback always if we have inputs or need event handling (or just want to see our simulation progress) - if hasInputs || c.fmu.hasStateEvents || c.fmu.hasTimeEvents || showProgress - stepCb = FunctionCallingCallback((x, t, integrator) -> stepCompleted(c, x, t, integrator, _inputFunction, progressMeter, t_start, t_stop, fmusol); - func_everystep = true, - func_start = true) - push!(cbs, stepCb) - end - - if savingValues - dtypes = collect(fmi2DataTypeForValueReference(c.fmu.modelDescription, vr) for vr in recordValues) - fmusol.values = SavedValues(fmi2Real, Tuple{dtypes...}) - fmusol.valueReferences = copy(recordValues) - - savingCB = nothing - if saveat === nothing - savingCB = SavingCallback((u,t,integrator) -> saveValues(c, recordValues, u, t, integrator, _inputFunction), - fmusol.values) - else - savingCB = SavingCallback((u,t,integrator) -> saveValues(c, recordValues, u, t, integrator, _inputFunction), - fmusol.values, - saveat=saveat) - end - - push!(cbs, savingCB) - end - - if savingEventIndicators - dtypes = collect(fmi2Real for ei in recordEventIndicators) - fmusol.eventIndicators = SavedValues(fmi2Real, Tuple{dtypes...}) - fmusol.recordEventIndicators = copy(recordEventIndicators) - - savingCB = nothing - if saveat === nothing - savingCB = SavingCallback((u,t,integrator) -> saveEventIndicators(c, recordEventIndicators, u, t, integrator, _inputFunction), - fmusol.eventIndicators) - else - savingCB = SavingCallback((u,t,integrator) -> saveEventIndicators(c, recordEventIndicators, u, t, integrator, _inputFunction), - fmusol.eventIndicators, - saveat=saveat) - end - - push!(cbs, savingCB) - end - - if recordEigenvalues - dtypes = collect(Float64 for _ in 1:2*length(c.fmu.modelDescription.stateValueReferences)) - fmusol.eigenvalues = SavedValues(fmi2Real, Tuple{dtypes...}) - - savingCB = nothing - if saveat === nothing - savingCB = SavingCallback((u,t,integrator) -> saveEigenvalues(c, u, t, integrator, _inputFunction), - fmusol.eigenvalues) - else - savingCB = SavingCallback((u,t,integrator) -> saveEigenvalues(c, u, t, integrator, _inputFunction), - fmusol.eigenvalues, - saveat=saveat) - end - - push!(cbs, savingCB) - end - - for cb in callbacksAfter - push!(cbs, cb) - end - - # if auto_dt == true - # @assert solver !== nothing "fmi2SimulateME(...): `auto_dt=true` but no solver specified, this is not allowed." - # tmpIntegrator = init(c.problem, solver) - # dt = auto_dt_reset!(tmpIntegrator) - # end - - solveKwargs = Dict{Symbol, Any}() - - if dt !== nothing - solveKwargs[:dt] = dt - end - - if tolerance !== nothing - solveKwargs[:reltol] = tolerance - end - - if saveat !== nothing - solveKwargs[:saveat] = saveat - end - - if isnothing(solver) - fmusol.states = solve(c.problem; callback = CallbackSet(cbs...), dtmax=dtmax, solveKwargs..., kwargs...) - else - fmusol.states = solve(c.problem, solver; callback = CallbackSet(cbs...), dtmax=dtmax, solveKwargs..., kwargs...) - end - - fmusol.success = (fmusol.states.retcode == ReturnCode.Success) - - if !fmusol.success - @warn "FMU simulation failed with solver return code `$(fmusol.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, terminate) - - return fmusol -end - -export fmi2SimulateME - -# function fmi2SimulateME(fmu::FMU2, -# c::Union{AbstractArray{<:Union{FMU2Component, Nothing}}, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; -# x0::Union{AbstractArray{<:AbstractArray{<:Real}}, AbstractArray{<:Real}, Nothing} = nothing, -# parameters::Union{AbstractArray{<:Dict{<:Any, <:Any}}, Dict{<:Any, <:Any}, Nothing} = nothing, -# kwargs...) - -# return ThreadPool.foreach((c, x0, parameters) -> fmi2SimulateME(fmu, c; x0=x0, parameters=parameters, kwargs...), zip()) -# end - -############ Co-Simulation ############ - -""" - fmi2SimulateCS(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) - -Wrapper for `fmi2SimulateCS(fmu::FMU2, c::Union{FMU2Component, Nothing}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...)` without a provided FMU2. -(FMU2 `fmu` is taken from `c`) -""" -function fmi2SimulateCS(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) - fmi2SimulateCS(c.fmu, c, tspan; kwargs...) -end - -""" - fmi2SimulateCS(fmu::FMU2, - c::Union{FMU2Component, Nothing}=nothing, - tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; - [tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi2ValueReferenceFormat = nothing, - saveat = [], - 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, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing]) - -Simulate CS-FMU for the given simulation time interval. - -# Arguments -- `fmu::FMU2`: Mutable struct representing a FMU and all it instantiated instances. -- `c::Union{FMU2Component, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. -- `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)) - -- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or 0.0) -- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or 1e-3) -- `recordValues::fmi2ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` -- `saveat = nothing`: Time points to save values at (default = nothing: save at each communication timestep) -- `setup::Union{Bool, Nothing} = nothing`: call fmi2SetupExperiment, fmi2EnterInitializationMode and fmi2ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `reset::Union{Bool, Nothing} = nothing`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `instantiate::Union{Bool, Nothing} = nothing`: call fmi2Reset before each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi2FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU2ExecutionConfiguration`) -- `terminate::Union{Bool, Nothing} = nothing`: 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 communication step -- `inputFunction = nothing`: Function to get values for the input variables at each communication step. - - ## Pattern [`c`: current component, `t`: current time, returning array of values to be passed to `fmi2SetReal(..., inputValueReferences, inputFunction(...))`]: - - `inputFunction(t::fmi2Real)` - - `inputFunction(c::FMU2Component, t::fmi2Real)` - -- `showProgress::Bool = true`: print simulation progressmeter in REPL -- `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 - -# Returns: -- `fmusol::FMU2Solution`, containing bool `fmusol.success` and if keyword `recordValues` is set, the saved values as `fmusol.values`. - -See also [`fmi2Simulate`](@ref), [`fmi2SimulateME`](@ref). -""" -function fmi2SimulateCS(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi2ValueReferenceFormat = nothing, - saveat = [], - 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, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing) - - @assert fmi2IsCoSimulation(fmu) "fmi2SimulateCS(...): This function supports Co-Simulation FMUs only." - #@assert fmu.type == fmi2TypeCoSimulation "fmi2SimulateCS(...): This FMU supports Co-Simulation, but was instantiated in ME mode. Use `fmiLoad(...; type=:CS)`." - - # input function handling - inputValueReferences = prepareValueReference(fmu, inputValueReferences) - hasInputs = (length(inputValueReferences) > 0) - - _inputFunction = nothing - u = EMPTY_fmi2Real - u_refs = EMPTY_fmi2ValueReference - if hasInputs - _inputFunction = FMU2InputFunction(inputFunction, inputValueReferences) - u_refs = _inputFunction.vrs - end - - # outputs - y_refs = EMPTY_fmi2ValueReference - y = EMPTY_fmi2Real - 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 - variableSteps = fmi2IsCoSimulation(fmu) && fmu.modelDescription.coSimulation.canHandleVariableCommunicationStepSize - t_start = t_start === nothing ? fmi2GetDefaultStartTime(fmu.modelDescription) : t_start - t_start = t_start === nothing ? 0.0 : t_start - t_stop = t_stop === nothing ? fmi2GetDefaultStopTime(fmu.modelDescription) : t_stop - t_stop = t_stop === nothing ? 1.0 : t_stop - tolerance = tolerance === nothing ? fmi2GetDefaultTolerance(fmu.modelDescription) : tolerance - tolerance = tolerance === nothing ? 0.0 : tolerance - dt = dt === nothing ? fmi2GetDefaultStepSize(fmu.modelDescription) : dt - dt = dt === nothing ? 1e-3 : dt - - inputs = nothing - if hasInputs - inputValues = eval!(_inputFunction, nothing, nothing, t_start) - inputs = Dict(inputValueReferences .=> inputValues) - end - c, _ = prepareSolveFMU(fmu, c, fmi2TypeCoSimulation, instantiate, freeInstance, terminate, reset, setup, parameters, t_start, t_stop, 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="Simulating 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 - - 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 - fmi2DoStep(c, dt; currentCommunicationPoint=t) - 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...,) - DiffEqCallbacks.copyat_or_push!(fmusol.values.t, i, t) - DiffEqCallbacks.copyat_or_push!(fmusol.values.saveval, i, svalues, Val{false}) - - if progressMeter !== nothing - ProgressMeter.update!(progressMeter, floor(Integer, 1000.0*(t-t_start)/(t_stop-t_start)) ) - end - end - - if progressMeter !== nothing - ProgressMeter.finish!(progressMeter) - end - - fmusol.success = true # ToDo: Check successful simulation! - - finishSolveFMU(fmu, c, freeInstance, terminate) - - return fmusol -end - -export fmi2SimulateCS - -##### CS & ME ##### - -""" - fmi2Simulate(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) - -Wrapper for `fmi2Simulate(fmu::FMU2, c::Union{FMU2Component, Nothing}, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...)` without a provided FMU2. -(FMU2 `fmu` is taken from `c`) -""" -function fmi2Simulate(c::FMU2Component, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) - fmi2Simulate(c.fmu, c, tspan; kwargs...) -end - -# function (c::FMU2Component)(; t::Tuple{Float64, Float64}, kwargs...) -# fmi2Simulate(c, t; kwargs...) -# end - -# function (f::FMU2)(; t::Tuple{Float64, Float64}, kwargs...) -# fmi2Simulate(c.fmu, t; kwargs...) -# end - -""" - fmi2Simulate(args...) - -Starts a simulation of the `FMU2` for the matching type (`fmi2SimulateCS(args...)` or `fmi2SimulateME(args...)`); if both types are available, CS is preferred. - -See also [`fmi2SimulateCS`](@ref), [`fmi2SimulateME`](@ref). -""" -function fmi2Simulate(fmu::FMU2, c::Union{FMU2Component, Nothing}=nothing, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) - - if fmu.type == fmi2TypeCoSimulation - return fmi2SimulateCS(fmu, c, tspan; kwargs...) - elseif fmu.type == fmi2TypeModelExchange - return fmi2SimulateME(fmu, c, tspan; kwargs...) - else - error(unknownFMUType) - end -end - -export fmi2Simulate \ 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/FMI3/sim.jl b/src/FMI3/sim.jl deleted file mode 100644 index d8d0c664..00000000 --- a/src/FMI3/sim.jl +++ /dev/null @@ -1,1261 +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, DifferentialEquations.DiffEqCallbacks -import DifferentialEquations.SciMLBase: RightRootFind, ReturnCode - -using FMIImport: fmi3EnterInitializationMode, fmi3ExitInitializationMode, fmi3UpdateDiscreteStates, fmi3GetContinuousStates, fmi3GetNominalsOfContinuousStates, fmi3SetContinuousStates, fmi3GetContinuousStateDerivatives! -using FMIImport.FMICore: fmi3StatusOK, fmi3TypeCoSimulation, fmi3TypeModelExchange -using FMIImport.FMICore: fmi3InstanceState, fmi3InstanceStateInstantiated, fmi3InstanceStateInitializationMode, fmi3InstanceStateEventMode, fmi3InstanceStateContinuousTimeMode, fmi3InstanceStateTerminated, fmi3InstanceStateError, fmi3InstanceStateFatal -using FMIImport: FMU3Solution, FMU3Event - -using FMIImport.FMICore.ChainRulesCore - -import ProgressMeter - -############ Model-Exchange ############ - -# Read next time event from FMU and provide it to the integrator -function time_choice(c::FMU3Instance, integrator, tStart, tStop) - #@info "TC" - - discreteStatesNeedUpdate, terminateSimulation, nominalsOfContinuousStatesChanged, valuesOfContinuousStatesChanged, nextEventTimeDefined, nextEventTime = fmi3UpdateDiscreteStates(c) - - if nextEventTimeDefined == fmi3True - - if nextEventTime >= tStart && nextEventTime <= tStop - return nextEventTime - else - # the time event is outside the simulation range! - @debug "Next time event @$(c.eventInfo.nextEventTime)s is outside simulation time range ($(tStart), $(tStop)), skipping." - return nothing - end - else - return nothing - end -end - -# Handles events and returns the values and nominals of the changed continuous states. -function handleEvents(c::FMU3Instance) - # @assert c.state == fmi3InstanceStateEventMode "handleEvents(...): Must be in event mode!" - - # trigger the loop - discreteStatesNeedUpdate = fmi3True - nominalsChanged = fmi3False - valuesChanged = fmi3False - nextEventTimeDefined = fmi3False - nextEventTime = 0.0 - - while discreteStatesNeedUpdate == fmi3True - - # TODO set inputs - discreteStatesNeedUpdate, terminateSimulation, nominalsOfContinuousStatesChanged, valuesOfContinuousStatesChanged, nextEventTimeDefined, nextEventTime = fmi3UpdateDiscreteStates(c) - - if c.state != fmi3InstanceStateEventMode - fmi3EnterEventMode(c, c.stepEvent, c.stateEvent, c.rootsFound, Csize_t(c.fmu.modelDescription.numberOfEventIndicators), c.timeEvent) - end - # TODO inputEvent handling - discreteStatesNeedUpdate = fmi3True - while discreteStatesNeedUpdate == fmi3True - # update discrete states - discreteStatesNeedUpdate, terminateSimulation, nominalsOfContinuousStatesChanged, valuesOfContinuousStatesChanged, nextEventTimeDefined, nextEventTime = fmi3UpdateDiscreteStates(c) - - if valuesOfContinuousStatesChanged == fmi3True - valuesChanged = true - end - - if nominalsOfContinuousStatesChanged == fmi3True - nominalsChanged = true - end - - if terminateSimulation == fmi3True - @error "fmi3UpdateDiscreteStates returned error!" - end - end - end - fmi3EnterContinuousTimeMode(c) - @debug "handleEvents(_, $(enterEventMode), $(exitInContinuousMode)): rootsFound: $(c.rootsFound) valuesChanged: $(valuesChanged) continuousStates: $(fmi3GetContinuousStates(c))", - return valuesChanged, nominalsChanged - -end - -# Returns the event indicators for an FMU. -function condition(c::FMU3Instance, out::AbstractArray{<:Real}, x, t, integrator, inputFunction, inputValues::AbstractArray{fmi3ValueReference}) - if inputFunction !== nothing - fmi3SetFloat64(c, inputValues, inputFunction(c, x, t)) - end - - @assert c.state == fmi3InstanceStateContinuousTimeMode "condition(...): Must be called in mode continuous time." - - fmi3SetContinuousStates(c, x) - fmi3SetTime(c, t) - if inputFunction !== nothing - fmi3SetFloat64(c, inputValues, inputFunction(c, x, t)) - end - - # TODO check implementation of fmi3GetEventIndicators! mit abstract array - fmi3GetEventIndicators!(c, out, UInt(length(out))) - - # if length(indicators) > 0 - # for i in 1:length(indicators) - # if c.z_prev[i] < 0 && indicators[i] >= 0 - # c.rootsFound[i] = 1 - # elseif c.z_prev[i] > 0 && indicators[i] <= 0 - # c.rootsFound[i] = -1 - # else - # c.rootsFound[i] = 0 - # end - # c.stateEvent |= (c.rootsFound[i] != 0) - # # c.z_prev[i] = indicators[i] - # end - # end - - return nothing -end - -# Handles the upcoming events. -function affectFMU!(c::FMU3Instance, integrator, idx, inputFunction, inputValues::Array{fmi3ValueReference}, solution::FMU3Solution) - - @assert c.state == fmi3InstanceStateContinuousTimeMode "affectFMU!(...): Must be in continuous time mode!" - - # there are fx-evaluations before the event is handled, reset the FMU state to the current integrator step - fmi3SetContinuousStates(c, integrator.u) - fmi3SetTime(c, integrator.t) - if inputFunction !== nothing - fmi3SetFloat64(c, inputValues, inputFunction(c, integrator.u, integrator.t)) - end - - fmi3EnterEventMode(c, c.stepEvent, c.stateEvent, c.rootsFound, Csize_t(c.fmu.modelDescription.numberOfEventIndicators), c.timeEvent) - - # Event found - handle it - handleEvents(c) - - left_x = nothing - right_x = nothing - - if c.eventInfo.valuesOfContinuousStatesChanged == fmi3True - left_x = integrator.u - right_x = fmi3GetContinuousStates(c) - @debug "affectFMU!(...): Handled event at t=$(integrator.t), new state is $(new_u)" - integrator.u = right_x - - u_modified!(integrator, true) - #set_proposed_dt!(integrator, 1e-10) - else - u_modified!(integrator, false) - @debug "affectFMU!(...): Handled event at t=$(integrator.t), no new state." - end - - if c.eventInfo.nominalsOfContinuousStatesChanged == fmi3True - x_nom = fmi3GetNominalsOfContinuousStates(c) - end - - ignore_derivatives() do - if idx != -1 # -1 no event, 0, time event, >=1 state event with indicator - e = FMU3Event(integrator.t, UInt64(idx), left_x, right_x) - push!(solution.events, e) - end - end - - #fmi3EnterContinuousTimeMode(c) -end - -# Does one step in the simulation. -function stepCompleted(c::FMU3Instance, x, t, integrator, inputFunction, inputValues::AbstractArray{fmi3ValueReference}, progressMeter, tStart, tStop, solution::FMU3Solution) - - @assert c.state == fmi3InstanceStateContinuousTimeMode "stepCompleted(...): Must be in continuous time mode." - #@info "Step completed" - if progressMeter !== nothing - stat = 1000.0*(t-tStart)/(tStop-tStart) - if !isnan(stat) - stat = floor(Integer, stat) - ProgressMeter.update!(progressMeter, stat) - end - end - - # if length(indicators) > 0 - # c.stateEvent = fmi3False - - # for i in 1:length(indicators) - # if c.z_prev[i] < 0 && indicators[i] >= 0 - # c.rootsFound[i] = 1 - # elseif c.z_prev[i] > 0 && indicators[i] <= 0 - # c.rootsFound[i] = -1 - # else - # c.rootsFound[i] = 0 - # end - # c.stateEvent |= (c.rootsFound[i] != 0) - # c.z_prev[i] = indicators[i] - # end - # end - (status, enterEventMode, terminateSimulation) = fmi3CompletedIntegratorStep(c, fmi3True) - - if terminateSimulation == fmi3True - @error "stepCompleted(...): FMU requested termination!" - end - - if enterEventMode == fmi3True - affectFMU!(c, integrator, -1, inputFunction, inputValues, solution) - else - if inputFunction !== nothing - fmi3SetFloat64(c, inputValues, inputFunction(c, x, t)) - end - end -end - -# save FMU values -function saveValues(c::FMU3Instance, recordValues, x, t, integrator, inputFunction, inputValues) - - @assert c.state == fmi3InstanceStateContinuousTimeMode "saveValues(...): Must be in continuous time mode." - - #x_old = fmi3GetContinuousStates(c) - #t_old = c.t - - fmi3SetContinuousStates(c, x) - fmi3SetTime(c, t) - if inputFunction !== nothing - fmi3SetFloat64(c, inputValues, inputFunction(c, x, t)) - end - - #fmi3SetContinuousStates(c, x_old) - #fmi3SetTime(c, t_old) - - return (fmi3GetFloat64(c, recordValues)...,) -end - -# Returns the state derivatives of the FMU. -function fx(c::FMU3Instance, - dx::AbstractArray{<:Real}, - x::AbstractArray{<:Real}, - p::Tuple, - t::Real) - - # if isa(t, ForwardDiff.Dual) - # t = ForwardDiff.value(t) - # end - @debug "fx($(x), _, $(t))" - fmi3SetTime(c, t) - fmi3SetContinuousStates(c, x) - dx = fmi3GetContinuousStateDerivatives(c) - - # if all(isa.(dx, ForwardDiff.Dual)) - # dx_tmp = collect(ForwardDiff.value(e) for e in dx) - # fmi3GetContinuousStateDerivatives!(c, dx_tmp) - # T, V, N = fd_eltypes(dx) - # dx[:] = collect(ForwardDiff.Dual{T, V, N}(dx_tmp[i], ForwardDiff.partials(dx[i]) ) for i in 1:length(dx)) - # else - # fmi3GetContinuousStateDerivatives!(c, dx) - # end - - # y, dx = FMIImport.eval!(c, dx, nothing, nothing, x, nothing, nothing, t) - - return dx -end - -# same function as in FMI2_sim.jl -function _fx_fd(comp, dx, x, p, t) - - ȧrgs = [] - args = [] - - push!(ȧrgs, NoTangent()) - push!(args, fx) - - push!(ȧrgs, NoTangent()) - push!(args, comp) - - T = nothing - V = nothing - - dx_set = length(dx) > 0 && all(isa.(dx, ForwardDiff.Dual)) - x_set = length(x) > 0 && all(isa.(x, ForwardDiff.Dual)) - p_set = length(p) > 0 && all(isa.(p, ForwardDiff.Dual)) - t_set = isa(t, ForwardDiff.Dual) - - if dx_set - T, V, N = fd_eltypes(dx) - push!(ȧrgs, collect(ForwardDiff.partials(e) for e in dx)) - push!(args, collect(ForwardDiff.value(e) for e in dx)) - #@info "dx_set num=$(length(dx)) partials=$(length(ForwardDiff.partials(dx[1])))" - else - push!(ȧrgs, NoTangent()) - push!(args, dx) - end - - if x_set - T, V, N = fd_eltypes(x) - push!(ȧrgs, collect(ForwardDiff.partials(e) for e in x)) - push!(args, collect(ForwardDiff.value(e) for e in x)) - #@info "x_set num=$(length(x)) partials=$(length(ForwardDiff.partials(x[1])))" - else - push!(ȧrgs, NoTangent()) - push!(args, x) - end - - if p_set - T, V, N = fd_eltypes(p) - push!(ȧrgs, collect(ForwardDiff.partials(e) for e in p)) - push!(args, collect(ForwardDiff.value(e) for e in p)) - else - push!(ȧrgs, NoTangent()) - push!(args, p) - end - - if t_set - T, V, N = fd_eltypes(t) - push!(ȧrgs, ForwardDiff.partials(t)) - push!(args, ForwardDiff.value(t)) - else - push!(ȧrgs, NoTangent()) - push!(args, t) - end - - ȧrgs = (ȧrgs...,) - args = (args...,) - - y, _, sdx, sx, sp, st = ChainRulesCore.frule(ȧrgs, args...) - - ys = [] - - #[collect( ForwardDiff.Dual{Tx, Vx, Nx}(y[i], ForwardDiff.partials(x_partials[i], t_partials[i])) for i in 1:length(y) )...] - for i in 1:length(y) - is = NoTangent() - - if dx_set - is = sdx[i]#.values - end - if x_set - is = sx[i]#.values - end - - if p_set - is = sp[i]#.values - end - if t_set - is = st[i]#.values - end - - #display("dx: $dx") - #display("sdx: $sdx") - - #partials = (isdx, isx, isp, ist) - - #display(partials) - - - #V = Float64 - #N = length(partials) - #display("$T $V $N") - - #display(is) - - @assert is != ZeroTangent() && is != NoTangent() "is: $(is)" - - push!(ys, ForwardDiff.Dual{T, V, N}(y[i], is ) ) # ForwardDiff.Partials{N, V}(partials) - end - - ys -end - -import FMIImport: fmi3VariabilityConstant, fmi3InitialApprox, fmi3InitialExact -function setBeforeInitialization(mv::FMIImport.fmi3Variable) - return mv.variability != fmi3VariabilityConstant && mv.initial ∈ (fmi3InitialApprox, fmi3InitialExact) -end - -import FMIImport: fmi3CausalityInput, fmi3CausalityParameter, fmi3VariabilityTunable -function setInInitialization(mv::FMIImport.fmi3Variable) - return mv.causality == fmi3CausalityInput || (mv.causality != fmi3CausalityParameter && mv.variability == fmi3VariabilityTunable) || (mv.variability != fmi3VariabilityConstant && mv.initial == fmi3InitialExact) -end - -function prepareFMU(fmu::FMU3, c::Union{Nothing, FMU3Instance}, type::fmi3Type, instantiate::Union{Nothing, Bool}, terminate::Union{Nothing, Bool}, reset::Union{Nothing, Bool}, setup::Union{Nothing, Bool}, parameters::Union{Dict{<:Any, <:Any}, Nothing}, t_start, t_stop, tolerance; - x0::Union{AbstractArray{<:Real}, Nothing}=nothing, inputFunction=nothing, inputValueReferences=nothing) - - if instantiate === nothing - instantiate = fmu.executionConfig.instantiate - end - - if terminate === nothing - terminate = fmu.executionConfig.terminate - end - - if reset === nothing - reset = fmu.executionConfig.reset - end - - if setup === nothing - setup = fmu.executionConfig.setup - end - - c = nothing - - # instantiate (hard) - if instantiate - if type == fmi3TypeCoSimulation - c = fmi3InstantiateCoSimulation!(fmu) - elseif type == fmi3TypeModelExchange - c = fmi3InstantiateModelExchange!(fmu) - else - c = fmi3InstantiateScheduledExecution!(fmu) - end - else - if c === nothing - if length(fmu.instances) > 0 - c = fmu.instances[end] - else - @warn "Found no FMU instance, but executionConfig doesn't force allocation. Allocating one. Use `fmi3Instantiate(fmu)` to prevent this message." - if type == fmi3TypeCoSimulation - c = fmi3InstantiateCoSimulation!(fmu) - elseif type == fmi3TypeModelExchange - c = fmi3InstantiateModelExchange!(fmu) - else - c = fmi3InstantiateScheduledExecution!(fmu) - end - end - end - end - - @assert c !== nothing "No FMU instance available, allocate one or use `fmu.executionConfig.instantiate=true`." - - # soft terminate (if necessary) - if terminate - retcode = fmi3Terminate(c; soft=true) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Termination failed with return code $(retcode)." - end - - # soft reset (if necessary) - if reset - retcode = fmi3Reset(c; soft=true) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Reset failed with return code $(retcode)." - end - - # setup experiment (hard) - # TODO this part is handled by fmi3EnterInitializationMode - # if setup - # retcode = fmi2SetupExperiment(c, t_start, t_stop; tolerance=tolerance) - # @assert retcode == fmi3StatusOK "fmi3Simulate(...): Setting up experiment failed with return code $(retcode)." - # end - - # parameters - if parameters !== nothing - retcodes = fmi3Set(c, collect(keys(parameters)), collect(values(parameters)); filter=setBeforeInitialization) - @assert all(retcodes .== fmi3StatusOK) "fmi3Simulate(...): Setting initial parameters failed with return code $(retcode)." - end - - # inputs - inputs = nothing - if inputFunction !== nothing && inputValueReferences !== nothing - # set inputs - inputs = Dict{fmi3ValueReference, Any}() - - inputValues = nothing - if hasmethod(inputFunction, Tuple{FMU3Instance, fmi3Float64}) # CS - inputValues = inputFunction(c, t_start) - else # ME - inputValues = inputFunction(c, nothing, t_start) - end - - for i in 1:length(inputValueReferences) - vr = inputValueReferences[i] - inputs[vr] = inputValues[i] - end - end - - # inputs - if inputs !== nothing - retcodes = fmi3Set(c, collect(keys(inputs)), collect(values(inputs)); filter=setBeforeInitialization) - @assert all(retcodes .== fmi3StatusOK) "fmi3Simulate(...): Setting initial inputs failed with return code $(retcode)." - end - - # start state - if x0 !== nothing - #retcode = fmi3SetContinuousStates(c, x0) - #@assert retcode == fmi3StatusOK "fmi3Simulate(...): Setting initial state failed with return code $(retcode)." - retcodes = fmi3Set(c, fmu.modelDescription.stateValueReferences, x0; filter=setBeforeInitialization) - @assert all(retcodes .== fmi3StatusOK) "fmi3Simulate(...): Setting initial inputs failed with return code $(retcode)." - end - - # enter (hard) - if setup - retcode = fmi3EnterInitializationMode(c, t_start, t_stop; tolerance = tolerance) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Entering initialization mode failed with return code $(retcode)." - end - - # parameters - if parameters !== nothing - retcodes = fmi3Set(c, collect(keys(parameters)), collect(values(parameters)); filter=setInInitialization) - @assert all(retcodes .== fmi3StatusOK) "fmi3Simulate(...): Setting initial parameters failed with return code $(retcode)." - end - - if inputs !== nothing - retcodes = fmi3Set(c, collect(keys(inputs)), collect(values(inputs)); filter=setInInitialization) - @assert all(retcodes .== fmi3StatusOK) "fmi3Simulate(...): Setting initial inputs failed with return code $(retcode)." - end - - # start state - if x0 !== nothing - #retcode = fmi3SetContinuousStates(c, x0) - #@assert retcode == fmi3StatusOK "fmi3Simulate(...): Setting initial state failed with return code $(retcode)." - retcodes = fmi3Set(c, fmu.modelDescription.stateValueReferences, x0; filter=setInInitialization) - @assert all(retcodes .== fmi3StatusOK) "fmi3Simulate(...): Setting initial inputs failed with return code $(retcode)." - end - - # exit setup (hard) - if setup - retcode = fmi3ExitInitializationMode(c) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Exiting initialization mode failed with return code $(retcode)." - end - - if type == fmi3TypeModelExchange - if x0 === nothing - x0 = fmi3GetContinuousStates(c) - end - end - - return c, x0 -end - -function prepareFMU(fmu::Vector{FMU3}, c::Vector{Union{Nothing, FMU3Instance}}, type::Vector{fmi3Type}, instantiate::Union{Nothing, Bool}, freeInstance::Union{Nothing, Bool}, terminate::Union{Nothing, Bool}, reset::Union{Nothing, Bool}, setup::Union{Nothing, Bool}, parameters::Union{Vector{Union{Dict{<:Any, <:Any}, Nothing}}, Nothing}, t_start, t_stop, tolerance; - x0::Union{Vector{Union{Array{<:Real}, Nothing}}, Nothing}=nothing, initFct=nothing) - - ignore_derivatives() do - for i in 1:length(fmu) - - if instantiate === nothing - instantiate = fmu[i].executionConfig.instantiate - end - - if freeInstance === nothing - freeInstance = fmu[i].executionConfig.freeInstance - end - - if terminate === nothing - terminate = fmu[i].executionConfig.terminate - end - - if reset === nothing - reset = fmu[i].executionConfig.reset - end - - if setup === nothing - setup = fmu[i].executionConfig.setup - end - - # instantiate (hard) - if instantiate - # remove old one if we missed it (callback) - if c[i] !== nothing - if freeInstance - fmi3FreeInstance!(c[i]) - @debug "[AUTO-RELEASE INST]" - end - end - - if type[i] == fmi3TypeCoSimulation - c[i] = fmi3InstantiateCoSimulation!(fmu[i]) - elseif type[i] == fmi3TypeModelExchange - c[i] = fmi3InstantiateModelExchange!(fmu[i]) - else - c[i] = fmi3InstantiateScheduledExecution!(fmu[i]) - end - @debug "[NEW INST]" - else - if c[i] === nothing - c[i] = fmu[i].instances[end] - end - end - - # soft terminate (if necessary) - if terminate - retcode = fmi3Terminate(c[i]; soft=true) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Termination failed with return code $(retcode)." - end - - # soft reset (if necessary) - if reset - retcode = fmi3Reset(c[i]; soft=true) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Reset failed with return code $(retcode)." - end - - # enter setup (hard) - if setup - # retcode = fmi2SetupExperiment(c[i], t_start, t_stop; tolerance=tolerance) - # @assert retcode == fmi2StatusOK "fmi2Simulate(...): Setting up experiment failed with return code $(retcode)." - - retcode = fmi3EnterInitializationMode(c[i], t_start, t_stop; tolerance=tolerance) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Entering initialization mode failed with return code $(retcode)." - end - - if x0 !== nothing - if x0[i] !== nothing - retcode = fmi3SetContinuousStates(c[i], x0[i]) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Setting initial state failed with return code $(retcode)." - end - end - - if parameters !== nothing - if parameters[i] !== nothing - retcodes = fmi3Set(c[i], collect(keys(parameters[i])), collect(values(parameters[i])) ) - @assert all(retcodes .== fmi3StatusOK) "fmi3Simulate(...): Setting initial parameters failed with return code $(retcode)." - end - end - - if initFct !== nothing - initFct() - end - - # exit setup (hard) - if setup - retcode = fmi3ExitInitializationMode(c[i]) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Exiting initialization mode failed with return code $(retcode)." - end - - if type == fmi3TypeModelExchange - if x0 === nothing - if x0[i] === nothing - x0[i] = fmi3GetContinuousStates(c[i]) - end - end - end - end - - end # ignore_derivatives - - return c, x0 -end - -function finishFMU(fmu::FMU3, c::FMU3Instance, terminate::Union{Nothing, Bool}, freeInstance::Union{Nothing, Bool}) - - if c === nothing - return - end - - if terminate === nothing - terminate = fmu.executionConfig.terminate - end - - if freeInstance === nothing - freeInstance = fmu.executionConfig.freeInstance - end - - # soft terminate (if necessary) - if terminate - retcode = fmi3Terminate(c; soft=true) - @assert retcode == fmi3StatusOK "fmi3Simulate(...): Termination failed with return code $(retcode)." - end - - # freeInstance (hard) - if freeInstance - fmi3FreeInstance!(c) - end -end - -""" - fmi3SimulateME(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - -Wrapper for `fmi3SimulateME(fmu::FMU3, c::Union{FMU3Instance, Nothing}, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...)` without a provided FMU3. -(FMU3 `fmu` is taken from `c`) -""" -function fmi3SimulateME(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - fmi3SimulateME(c.fmu, c, t_start, t_stop; kwargs...) -end - -# sets up the ODEProblem for simulating a ME-FMU -function setupODEProblem(c::FMU3Instance, x0::AbstractArray{fmi3Float64}, t_start::fmi3Float64, t_stop::fmi3Float64; p=(), customFx=nothing) - if customFx === nothing - customFx = (dx, x, p, t) -> fx(c, dx, x, p, t) - end - - p = () - c.problem = ODEProblem(customFx, x0, (t_start, t_stop), p,) - - return c.problem -end - -""" - fmi3SimulateME(fmu::FMU3, - c::Union{FMU3Instance, Nothing}=nothing, - t_start::Union{Real, Nothing} = nothing, - t_stop::Union{Real, Nothing} = nothing; - [tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - solver = nothing, - customFx = nothing, - recordValues::fmi3ValueReferenceFormat = 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::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, - dtmax::Union{Real, Nothing} = nothing, - callbacks = [], - showProgress::Bool = true, - kwargs...]) - -Simulate ME-FMU for the given simulation time interval. - -State- and Time-Events are handled correctly. - -# Arguments -- `fmu::FMU3`: Mutable struct representing a FMU and all it instantiated instances. -- `c::Union{FMU3Instance, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. -- `t_start::Union{Real, Nothing} = nothing`: Simulation-time-span start time (default = nothing: use default value from `fmu`'s model description or 0.0) -- `t_stop::Union{Real, Nothing} = nothing`: Simulation-time-span stop time (default = nothing: use default value from `fmu`'s model description or 1.0) - -- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) -- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or -if not available- default from DifferentialEquations.jl) -- `solver = nothing`: Any Julia-supported ODE-solver (default = nothing: use DifferentialEquations.jl default solver) -- `customFx`: [deprecated] custom state derivative function ẋ=f(x,t) -- `recordValues::fmi3ValueReferenceFormat` = 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) -- `x0::Union{AbstractArray{<:Real}, Nothing} = nothing`: inital fmu State (default = nothing: use current or default-inital fmu state) -- `setup::Union{Bool, Nothing} = nothing`: call fmi3EnterInitializationMode and fmi3ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `reset::Union{Bool, Nothing} = nothing`: call fmi3Reset before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `instantiate::Union{Bool, Nothing} = nothing`: call fmi3Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi3FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `terminate::Union{Bool, Nothing} = nothing`: call fmi3Terminate after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `inputValueReferences::fmi3ValueReferenceFormat = 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. - - ## Pattern [`c`: current instance, `u`: current state ,`t`: current time, returning array of values to be passed to `fmi3SetFloat64(..., inputValueReferences, inputFunction(...))`]: - - `inputFunction(t::fmi3Float64)` - - `inputFunction(c::FMU3Instance, t::fmi3Float64)` - - `inputFunction(c::FMU3Instance, u::Union{AbstractArray{fmi3Float64,1}, Nothing})` - - `inputFunction(u::Union{AbstractArray{fmi3Float64,1}, Nothing}, t::fmi3Float64)` - - `inputFunction(c::FMU3Instance, u::Union{AbstractArray{fmi3Float64,1}, Nothing}, t::fmi3Float64)` - -- `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 -- `dtmax::Union{Real, Nothing} = nothing`: sets the maximum stepszie for the solver (default = nothing: use `(Simulation-time-span-length)/100.0`) -- `callbacks = []`: functions that are to be called at each solver time step -- `showProgress::Bool = true`: print simulation progressmeter in REPL -- `kwargs...`: keyword arguments that get passed onto the solvers solve call - -# Returns: -- If keyword `recordValues` has value `nothing`, a struct of type `ODESolution`. -- If keyword `recordValues` is set, a tuple of type `(ODESolution, DiffEqCallbacks.SavedValues)`. - -See also [`fmi3Simulate`](@ref), [`fmi3SimulateCS`](@ref), [`fmi3SimulateSE`](@ref). -""" -function fmi3SimulateME(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - solver = nothing, - customFx = nothing, - recordValues::fmi3ValueReferenceFormat = 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::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing, - dtmax::Union{Real, Nothing} = nothing, - callbacks = [], - showProgress::Bool = true, - kwargs...) - @warn "ME-simulation is not working properly right now!" - - @assert fmi3IsModelExchange(fmu) "fmi3SimulateME(...): This function supports Model Exchange FMUs only." - #@assert fmu.type == fmi3TypeModelExchange "fmi3SimulateME(...): This FMU supports Model Exchange, but was instantiated in CS mode. Use `fmiLoad(...; type=:ME)`." # TODO why not using this?? - - # input function handling - _inputFunction = nothing - if inputFunction !== nothing - if hasmethod(inputFunction, Tuple{fmi3Float64}) - _inputFunction = (c, u, t) -> inputFunction(t) - elseif hasmethod(inputFunction, Tuple{Union{FMU3Instance, Nothing}, fmi3Float64}) - _inputFunction = (c, u, t) -> inputFunction(c, t) - elseif hasmethod(inputFunction, Tuple{Union{FMU3Instance, Nothing}, AbstractArray{fmi3Float64,1}}) - _inputFunction = (c, u, t) -> inputFunction(c, u) - elseif hasmethod(inputFunction, Tuple{AbstractArray{fmi3Float64,1}, fmi3Float64}) - _inputFunction = (c, u, t) -> inputFunction(u, t) - else - _inputFunction = inputFunction - end - @assert hasmethod(_inputFunction, Tuple{FMU3Instance, Union{AbstractArray{fmi3Float64,1}, Nothing}, fmi3Float64}) "The given input function does not fit the needed input function pattern for ME-FMUs, which are: \n- `inputFunction(t::fmi3Float64)`\n- `inputFunction(comp::FMU3Instance, t::fmi3Float64)`\n- `inputFunction(comp::FMU3Instance, u::Union{AbstractArray{fmi3Float64,1}, Nothing})`\n- `inputFunction(u::Union{AbstractArray{fmi3Float64,1}, Nothing}, t::fmi3Float64)`\n- `inputFunction(comp::FMU3Instance, u::Union{AbstractArray{fmi3Float64,1}, Nothing}, t::fmi3Float64)`" - end - - recordValues = prepareValueReference(fmu, recordValues) - inputValueReferences = prepareValueReference(fmu, inputValueReferences) - - fmusol = FMU3Solution(fmu) - - savingValues = (length(recordValues) > 0) - hasInputs = (length(inputValueReferences) > 0) - hasParameters = (parameters !== nothing) - hasStartState = (x0 !== nothing) - - cbs = [] - - for cb in callbacks - push!(cbs, cb) - end - - if t_start === nothing - t_start = fmi3GetDefaultStartTime(fmu.modelDescription) - - if t_start === nothing - t_start = 0.0 - @info "No `t_start` choosen, no `t_start` availabel in the FMU, auto-picked `t_start=0.0`." - end - end - - if t_stop === nothing - t_stop = fmi3GetDefaultStopTime(fmu.modelDescription) - - if t_stop === nothing - t_stop = 1.0 - @warn "No `t_stop` choosen, no `t_stop` availabel in the FMU, auto-picked `t_stop=1.0`." - end - end - - if tolerance === nothing - tolerance = fmi3GetDefaultTolerance(fmu.modelDescription) - # if no tolerance is given, pick auto-setting from DifferentialEquations.jl - end - - if dt === nothing - dt = fmi3GetDefaultStepSize(fmu.modelDescription) - # if no dt is given, pick auto-setting from DifferentialEquations.jl - end - - if dtmax === nothing - dtmax = (t_stop-t_start)/100.0 - end - - # argument `tolerance=nothing` here, because ME-FMUs doesn't support tolerance control (no solver included) - # tolerance for the solver is set-up later in this function - c, x0 = prepareFMU(fmu, c, fmi3TypeModelExchange, instantiate, terminate, reset, setup, parameters, t_start, t_stop, nothing; x0=x0, inputFunction=_inputFunction, inputValueReferences=inputValueReferences) - - # from here on, we are in event mode, if `setup=false` this is the job of the user - #@assert c.state == fmi3InstanceStateEventMode "FMU needs to be in event mode after setup." - - # if x0 === nothing - # x0 = fmi3GetContinuousStates(c) - # x0_nom = fmi3GetNominalsOfContinuousStates(c) - # end - - # initial event handling - # fmi3EnterEventMode(c, c.stepEvent, c.stateEvent, c.rootsFound, Csize_t(c.fmu.modelDescription.numberOfEventIndicators), c.timeEvent) - handleEvents(c) - #fmi3EnterContinuousTimeMode(c) - - c.fmu.hasStateEvents = (c.fmu.modelDescription.numberOfEventIndicators > 0) - # c.fmu.hasTimeEvents = (c.eventInfo.nextEventTimeDefined == fmi2True) - c.fmu.hasTimeEvents = fmi3False - - setupODEProblem(c, x0, t_start, t_stop; customFx=customFx) - - 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 - - # callback functions - - if c.fmu.hasTimeEvents - timeEventCb = IterativeCallback((integrator) -> time_choice(c, integrator, t_start, t_stop), - (integrator) -> affectFMU!(c, integrator, 0, _inputFunction, inputValueReferences, fmusol), Float64; - initial_affect = false, # (c.eventInfo.nextEventTime == t_start) - save_positions=(false,false)) - push!(cbs, timeEventCb) - end - - if c.fmu.hasStateEvents - - eventCb = VectorContinuousCallback((out, x, t, integrator) -> condition(c, out, x, t, integrator, _inputFunction, inputValueReferences), - (integrator, idx) -> affectFMU!(c, integrator, idx, _inputFunction, inputValueReferences, fmusol), - Int64(c.fmu.modelDescription.numberOfEventIndicators); - rootfind = RightRootFind, - save_positions=(false,false)) - push!(cbs, eventCb) - end - - # use step callback always if we have inputs or need event handling (or just want to see our simulation progress) - if hasInputs || c.fmu.hasStateEvents || c.fmu.hasTimeEvents || showProgress - stepCb = FunctionCallingCallback((x, t, integrator) -> stepCompleted(c, x, t, integrator, _inputFunction, inputValueReferences, progressMeter, t_start, t_stop, fmusol); - func_everystep = true, - func_start = true) - push!(cbs, stepCb) - end - - if savingValues - fmusol.values = SavedValues(Float64, Tuple{collect(Float64 for i in 1:length(recordValues))...}) - fmusol.valueReferences = copy(recordValues) - - if saveat === nothing - savingCB = SavingCallback((u,t,integrator) -> saveValues(c, recordValues, u, t, integrator, _inputFunction, inputValueReferences), - fmusol.values) - else - savingCB = SavingCallback((u,t,integrator) -> saveValues(c, recordValues, u, t, integrator, _inputFunction, inputValueReferences), - fmusol.values, - saveat=saveat) - end - - push!(cbs, savingCB) - end - - # if auto_dt == true - # @assert solver !== nothing "fmi2SimulateME(...): `auto_dt=true` but no solver specified, this is not allowed." - # tmpIntegrator = init(c.problem, solver) - # dt = auto_dt_reset!(tmpIntegrator) - # end - - solveKwargs = Dict{Symbol, Any}() - - if dt !== nothing - solveKwargs[:dt] = dt - end - - if tolerance !== nothing - solveKwargs[:reltol] = tolerance - end - - if saveat !== nothing - solveKwargs[:saveat] = saveat - end - - if solver === nothing - fmusol.states = solve(c.problem; callback = CallbackSet(cbs...), dtmax=dtmax, solveKwargs..., kwargs...) - else - fmusol.states = solve(c.problem, solver; callback = CallbackSet(cbs...), dtmax=dtmax, solveKwargs..., kwargs...) - end - - fmusol.success = (fmusol.states.retcode == ReturnCode.Success) - - # cleanup progress meter - if showProgress - ProgressMeter.finish!(progressMeter) - end - - finishFMU(fmu, c, terminate, freeInstance) - - return fmusol -end - -export fmi3SimulateME - -############ Co-Simulation ############ - -""" - fmi3SimulateCS(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - -Wrapper for `fmi3SimulateCS(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...)` without a provided FMU3. -(FMU3 `fmu` is taken from `c`) -""" -function fmi3SimulateCS(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - fmi3SimulateCS(c.fmu, c, t_start, t_stop; kwargs...) -end - -""" - fmi3SimulateCS(fmu::FMU3, - c::Union{FMU3Instance, Nothing}=nothing, - t_start::Union{Real, Nothing} = nothing, - t_stop::Union{Real, Nothing} = nothing; - [tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi3ValueReferenceFormat = nothing, - saveat = [], - 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::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing]) - -Simulate CS-FMU for the given simulation time interval. - -# Arguments -- `fmu::FMU3`: Mutable struct representing a FMU and all it instantiated instances. -- `c::Union{FMU3Instance, Nothing}=nothing`: Mutable struct representing an instantiated instance of a FMU. -- `t_start::Union{Real, Nothing} = nothing`: Simulation-time-span start time (default = nothing: use default value from `fmu`'s model description or 0.0) -- `t_stop::Union{Real, Nothing} = nothing`: Simulation-time-span stop time (default = nothing: use default value from `fmu`'s model description or 1.0) - -- `tolerance::Union{Real, Nothing} = nothing`: tolerance for the solver (default = nothing: use default value from `fmu`'s model description or 0.0) -- `dt::Union{Real, Nothing} = nothing`: stepszie for the solver (default = nothing: use default value from `fmu`'s model description or 1e-3) -- `solver = nothing`: Any Julia-supported ODE-solver (default = nothing: use DifferentialEquations.jl default solver) -- `recordValues::fmi3ValueReferenceFormat` = nothing: Array of variables (Strings or variableIdentifiers) to record. Results are returned as `DiffEqCallbacks.SavedValues` -- `saveat = nothing`: Time points to save values at (default = nothing: save at each communication timestep) -- `setup::Union{Bool, Nothing} = nothing`: call fmi3EnterInitializationMode and fmi3ExitInitializationMode before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `reset::Union{Bool, Nothing} = nothing`: call fmi3Reset before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `instantiate::Union{Bool, Nothing} = nothing`: call fmi3Instantiate! before each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `freeInstance::Union{Bool, Nothing} = nothing`: call fmi3FreeInstance after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `terminate::Union{Bool, Nothing} = nothing`: call fmi3Terminate after each step (default = nothing: use value from `fmu`'s `FMU3ExecutionConfiguration`) -- `inputValueReferences::fmi3ValueReferenceFormat = nothing`: Input variables (Strings or variableIdentifiers) to set at each communication step -- `inputFunction = nothing`: Function to get values for the input variables at each communication step. - - ## Pattern [`c`: current instance, `t`: current time, returning array of values to be passed to `fmi3SetFloat64(..., inputValueReferences, inputFunction(...))`]: - - `inputFunction(t::fmi3Float64)` - - `inputFunction(c::FMU3Instance, t::fmi3Float64)` - -- `showProgress::Bool = true`: print simulation progressmeter in REPL -- `parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing`: Dict of parameter variables (strings or variableIdentifiers) and values (Boolean, String, Float64, ...) to set parameters during initialization - -# Returns: -- `fmusol::FMU3Solution`, containing bool `fmusol.success` and if keyword `recordValues` is set, the saved values as `fmusol.values`. - -See also [`fmi3Simulate`](@ref), [`fmi3SimulateME`](@ref), [`fmi3SimulateSE`](@ref). -""" -function fmi3SimulateCS(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi3ValueReferenceFormat = nothing, - saveat = [], - 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::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing) - - @assert fmi3IsCoSimulation(fmu) "fmi3SimulateCS(...): This function supports Co-Simulation FMUs only." - - # input function handling - _inputFunction = nothing - if inputFunction != nothing - if hasmethod(inputFunction, Tuple{fmi3Float64}) - _inputFunction = (c, t) -> inputFunction(t) - else - _inputFunction = inputFunctiont - end - @assert hasmethod(_inputFunction, Tuple{FMU3Instance, fmi3Float64}) "The given input function does not fit the needed input function pattern for CS-FMUs, which are: \n- `inputFunction(t::fmi3Float64)`\n- `inputFunction(comp::FMU3Instance, t::fmi3Float64)`" - end - - fmusol = FMU3Solution(fmu) - - - recordValues = prepareValueReference(fmu, recordValues) - inputValueReferences = prepareValueReference(fmu, inputValueReferences) - hasInputs = (length(inputValueReferences) > 0) - - variableSteps = fmi3IsCoSimulation(fmu) && fmu.modelDescription.coSimulation.canHandleVariableCommunicationStepSize - - t_start = t_start === nothing ? fmi3GetDefaultStartTime(fmu.modelDescription) : t_start - t_start = t_start === nothing ? 0.0 : t_start - t_stop = t_stop === nothing ? fmi3GetDefaultStopTime(fmu.modelDescription) : t_stop - t_stop = t_stop === nothing ? 1.0 : t_stop - tolerance = tolerance === nothing ? fmi3GetDefaultTolerance(fmu.modelDescription) : tolerance - tolerance = tolerance === nothing ? 0.0 : tolerance - dt = dt === nothing ? fmi3GetDefaultStepSize(fmu.modelDescription) : dt - dt = dt === nothing ? 1e-3 : dt - - c, _ = prepareFMU(fmu, c, fmi3TypeCoSimulation, instantiate, terminate, reset, setup, parameters, t_start, t_stop, tolerance; inputFunction=_inputFunction, inputValueReferences=inputValueReferences) - - # 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 - - record = length(recordValues) > 0 - - progressMeter = nothing - if showProgress - progressMeter = ProgressMeter.Progress(1000; desc="Simulating CS-FMU ...", color=:blue, dt=1.0) #, barglyphs=ProgressMeter.BarGlyphs("[=> ]")) - ProgressMeter.update!(progressMeter, 0) # show it! - end - - #numDigits = length(string(round(Integer, 1/dt))) - noSetFMUStatePriorToCurrentPoint = fmi3False - eventEncountered = fmi3False - terminateSimulation = fmi3False - earlyReturn = fmi3False - lastSuccessfulTime = fmi3Float64(0.0) - - if record - fmusol.values = SavedValues(Float64, Tuple{collect(Float64 for i in 1:length(recordValues))...} ) - fmusol.valueReferences = copy(recordValues) - - i = 1 - - svalues = (fmi3GetFloat64(c, recordValues)...,) - DiffEqCallbacks.copyat_or_push!(fmusol.values.t, i, t) - DiffEqCallbacks.copyat_or_push!(fmusol.values.saveval, i, svalues, Val{false}) - - while t < t_stop - if variableSteps - if length(saveat) > i - dt = saveat[i+1] - saveat[i] - else - dt = t_stop - saveat[i] - end - end - - if _inputFunction !== nothing - fmi3SetFloat64(fmu, inputValueReferences, _inputFunction(c, t)) - end - - fmi3DoStep!(fmu, t, dt, true, eventEncountered, terminateSimulation, earlyReturn, lastSuccessfulTime) - if eventEncountered == fmi3True - @warn "Event handling" - end - if terminateSimulation == fmi3True - @error "fmi3DoStep returned error!" - end - if earlyReturn == fmi3True - @warn "early Return" - end - t = t + dt #round(t + dt, digits=numDigits) - i += 1 - - svalues = (fmi3GetFloat64(c, recordValues)...,) - DiffEqCallbacks.copyat_or_push!(fmusol.values.t, i, t) - DiffEqCallbacks.copyat_or_push!(fmusol.values.saveval, i, svalues, Val{false}) - - if progressMeter !== nothing - ProgressMeter.update!(progressMeter, floor(Integer, 1000.0*(t-t_start)/(t_stop-t_start)) ) - end - end - - if progressMeter !== nothing - ProgressMeter.finish!(progressMeter) - end - - fmusol.success = true - - else - i = 1 - while t < t_stop - if variableSteps - if length(saveat) > i - dt = saveat[i+1] - saveat[i] - else - dt = t_stop - saveat[i] - end - end - - if _inputFunction !== nothing - fmi3SetFloat64(fmu, inputValues, _inputFunction(c, t)) - end - - fmi3DoStep!(fmu, t, dt, true, eventEncountered, terminateSimulation, earlyReturn, lastSuccessfulTime) - if eventEncountered == fmi3True - @warn "Event handling" - end - if terminateSimulation == fmi3True - @error "fmi3DoStep returned error!" - end - if earlyReturn == fmi3True - @warn "early Return" - end - t = t + dt #round(t + dt, digits=numDigits) - i += 1 - - if progressMeter !== nothing - ProgressMeter.update!(progressMeter, floor(Integer, 1000.0*(t-t_start)/(t_stop-t_start)) ) - end - end - - if progressMeter !== nothing - ProgressMeter.finish!(progressMeter) - end - - fmusol.success = true - end - - finishFMU(fmu, c, terminate, freeInstance) - - return fmusol -end - -export fmi3SimulateCS - -# TODO simulate ScheduledExecution -""" - fmi3SimulateSE(fmu::FMU3, - c::Union{FMU3Instance, Nothing}=nothing, - t_start::Union{Real, Nothing} = nothing, - t_stop::Union{Real, Nothing} = nothing; - [tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi3ValueReferenceFormat = nothing, - saveat = [], - 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::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing]) - -Simulate SE-FMU; not yet implemented in library - -See also [`fmi3Simulate`](@ref), [`fmi3SimulateME`](@ref), [`fmi3SimulateCS`](@ref). -""" -function fmi3SimulateSE(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; - tolerance::Union{Real, Nothing} = nothing, - dt::Union{Real, Nothing} = nothing, - recordValues::fmi3ValueReferenceFormat = nothing, - saveat = [], - 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::fmi3ValueReferenceFormat = nothing, - inputFunction = nothing, - showProgress::Bool=true, - parameters::Union{Dict{<:Any, <:Any}, Nothing} = nothing) @assert false "Not implemented" -end - -export fmi3SimulateSE - -##### CS & ME ##### - -""" - fmi3Simulate(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - -Wrapper for `fmi3Simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...)` without a provided FMU3. -(FMU3 `fmu` is taken from `c`) -""" -function fmi3Simulate(c::FMU3Instance, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - fmi3Simulate(c.fmu, c, t_start, t_stop; kwargs...) -end - -""" - fmi3Simulate(args...) - -Starts a simulation of the `FMU3` for the matching type (`fmi3SimulateCS(args...)`, `fmi3SimulateME(args...)` or `fmi3SimulateSE(args...)`); if multiple types are available, CS is preferred over ME, over SE. - -See also [`fmi3SimulateCS`](@ref), [`fmi3SimulateME`](@ref), [`fmi3SimulateSE`](@ref). -""" -function fmi3Simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, t_start::Union{Real, Nothing} = nothing, t_stop::Union{Real, Nothing} = nothing; kwargs...) - - if fmu.type == fmi3TypeCoSimulation - return fmi3SimulateCS(fmu, c, t_start, t_stop; kwargs...) - elseif fmu.type == fmi3TypeModelExchange - return fmi3SimulateME(fmu, c, t_start, t_stop; kwargs...) - elseif fmu.type == fmi3TypeScheduledExecution - return fmi3SimulateSE(fmu, c, t_start, t_stop; kwargs...) - else - error(unknownFMUType) - end -end - -export fmi3Simulate 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..ecc5be89 --- /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(f::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 9b63a364..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 "Unknwon 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 2b364ddc..424fc45b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,175 +8,95 @@ using FMIZoo using Test 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 currrently 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 65% rename from test/FMI2/sim_ME.jl rename to test/sim_ME.jl index afa7ef1f..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 polynominal 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 From b4820366c7b6873787f21a0f7765fc9750795324 Mon Sep 17 00:00:00 2001 From: TT Date: Thu, 20 Jun 2024 07:46:16 +0200 Subject: [PATCH 02/10] docu --- README.md | 6 +++--- docs/src/features.md | 46 +++++++++++++++++++++++--------------------- src/sim.jl | 2 +- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 4644bef9..886333f8 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ [![FMI Downloads](https://shields.io/endpoint?url=https://pkgs.genieframework.com/api/v1/badge/FMI)](https://pkgs.genieframework.com?packages=FMI) ## Breaking Changes in FMI.jl v1.0.0 -If you want to migrate your project from FMI.jl < v1.0.0 to >= v1.0.0, you will face some breaking changes - but they are worth it as you will see! +If you want to migrate your project from FMI.jl < v1.0.0 to >= v1.0.0, you will face some breaking changes - but they are worth it as you will see! -- Many functions, that are not part of the FMI-standard, had the prefix `fmi2...` or `fmi3...`. This wasn't 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. +- 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. - Wrapper functions where removed, because that is not the Julia way. In most cases, this will not affect your code. @@ -108,7 +108,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) diff --git a/docs/src/features.md b/docs/src/features.md index 8b18b78f..31fe3bc2 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 ... - 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) -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*. As a result, you can use implicite 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 implicite 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/src/sim.jl b/src/sim.jl index ecc5be89..b0a568f2 100644 --- a/src/sim.jl +++ b/src/sim.jl @@ -76,7 +76,7 @@ function simulate(fmu::FMU3, c::Union{FMU3Instance, Nothing}=nothing, tspan::Uni end end simulate(c::FMUInstance, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulate(c.fmu, c, tspan; kwargs...) -simulate(f::FMU, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulate(fmu, nothing, tspan; kwargs...) +simulate(fmu::FMU, tspan::Union{Tuple{Float64, Float64}, Nothing}=nothing; kwargs...) = simulate(fmu, nothing, tspan; kwargs...) export simulate """ From 00edf8a3054e4371470ed40f1b4e8b89605a25e8 Mon Sep 17 00:00:00 2001 From: TT Date: Wed, 17 Jul 2024 15:12:43 +0200 Subject: [PATCH 03/10] updated readme, relaxed compat --- Project.toml | 2 +- README.md | 50 ++++++++++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Project.toml b/Project.toml index 21771692..0d2cc7c0 100644 --- a/Project.toml +++ b/Project.toml @@ -9,7 +9,7 @@ FMIImport = "9fcbc62e-52a0-44e9-a616-1359a0008194" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [compat] -FMIExport = "0.4.0" +FMIExport = "0.4.0, 0.3.0" FMIImport = "1.0.0" LinearAlgebra = "1" julia = "1.6" diff --git a/README.md b/README.md index 886333f8..6deb36fc 100644 --- a/README.md +++ b/README.md @@ -2,33 +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) +| | | +|---|---| +| 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) | +| 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://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 v1.0.0 -If you want to migrate your project from FMI.jl < v1.0.0 to >= v1.0.0, you will face some breaking changes - but they are worth it as you will see! +## 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. -- 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] 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. -- Wrapper functions where removed, because that is not the Julia way. In most cases, this will not affect your code. +- [x] Wrapper functions where removed, because that is not the Julia way. In most cases, this will not affect your code. -- FMICore.jl and FMIImport.jl were divided into FMICore.jl, FMIImport.jl and FMIBase.jl. FMICore.jl now holds the pure standard definition (C-types and -functions), while FMIBase.jl holds everything that is needed on top of that in FMIImport.jl as well as in FMIExport.jl. +- [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). -- We tried to document every function, if you find undocumented user-level functions, please open an issue or PR. +- [ ] Updated all library tests for a better code coverage. -- Dependencies are reduced a little, to make the libraries more light-weight. +- [ ] We tried to document every function, if you find undocumented user-level functions, please open an issue or PR. -- RAM is now auto-released, for maximum performance you can use FMUs in blocks (like file reading/writing). +- [ ] 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. @@ -124,6 +133,3 @@ During development of new implementations or optimizations on exisitng code, one - **#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 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. - -## Interested in Hybrid Modelling in Julia using FMUs? -See [*FMIFlux.jl*](https://github.com/ThummeTo/FMIFlux.jl). From 068723bfd5b58d9203391864e24117ed4f285982 Mon Sep 17 00:00:00 2001 From: TT Date: Fri, 9 Aug 2024 16:14:39 +0200 Subject: [PATCH 04/10] modified project.tomlx --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 0d2cc7c0..21771692 100644 --- a/Project.toml +++ b/Project.toml @@ -9,7 +9,7 @@ FMIImport = "9fcbc62e-52a0-44e9-a616-1359a0008194" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [compat] -FMIExport = "0.4.0, 0.3.0" +FMIExport = "0.4.0" FMIImport = "1.0.0" LinearAlgebra = "1" julia = "1.6" From 5be7ef6ef752a2b4deb853e82cbab5a47ab6526c Mon Sep 17 00:00:00 2001 From: Simon Exner <43469235+0815Creeper@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:34:34 +0200 Subject: [PATCH 05/10] removed num_downloads badge, added new doc-strings to manual (#227) (api for badge currently down since 01-2024, screws up link-checking of documenter, markdown comment is not possible with documenter -> deletion) Co-authored-by: ThummeTo <83663542+ThummeTo@users.noreply.github.com> --- docs/src/fmi2_lowlevel_library_functions.md | 3 +++ docs/src/fmi_lowlevel_library_types.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/docs/src/fmi2_lowlevel_library_functions.md b/docs/src/fmi2_lowlevel_library_functions.md index d3feb5dc..3a316dc7 100644 --- a/docs/src/fmi2_lowlevel_library_functions.md +++ b/docs/src/fmi2_lowlevel_library_functions.md @@ -123,4 +123,7 @@ fmi2GetUnit fmi2GetDeclaredType fmi2GetInitial fmi2GetSimpleTypeAttributeStruct +fmi2GetDiscreteStates +fmi2GetDiscreteStates! +fmi2SetDiscreteStates ``` diff --git a/docs/src/fmi_lowlevel_library_types.md b/docs/src/fmi_lowlevel_library_types.md index 12256adb..af5dc419 100644 --- a/docs/src/fmi_lowlevel_library_types.md +++ b/docs/src/fmi_lowlevel_library_types.md @@ -2,8 +2,10 @@ ```@docs FMU +FMUInstance FMUSolution FMUEvent +FMUSnapshot FMUExecutionConfiguration FMULogLevel ``` \ No newline at end of file From 75161803dd583977f3ac0583995511130914af1e Mon Sep 17 00:00:00 2001 From: TT Date: Fri, 9 Aug 2024 16:57:51 +0200 Subject: [PATCH 06/10] fixed cross checks (FMI2) --- cross_checks/cross_check.jl | 12 +++++----- cross_checks/cross_check_config.jl | 35 +----------------------------- cross_checks/cross_check_lib.jl | 4 ++-- 3 files changed, 9 insertions(+), 42 deletions(-) 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 = [] From 25265552a5cc35d2d03da73e9bdebb30188a7dfb Mon Sep 17 00:00:00 2001 From: Simon Exner <43469235+0815Creeper@users.noreply.github.com> Date: Mon, 19 Aug 2024 10:01:50 +0200 Subject: [PATCH 07/10] fixed doc for 0.14 --- README.md | 4 +- docs/Project.toml | 1 + docs/make.jl | 10 +- docs/src/deprecated.md | 42 -------- docs/src/examples/overview.md | 1 - docs/src/fmi-tool-info.md | 2 +- docs/src/fmi2_lowlevel_CS_functions.md | 1 + docs/src/fmi2_lowlevel_library_constants.md | 45 ++++++++- docs/src/fmi2_lowlevel_library_functions.md | 43 +++----- docs/src/fmi2_lowlevel_library_types.md | 30 ------ ...mi2_lowlevel_modeldescription_functions.md | 52 ++-------- docs/src/fmi3_lowlevel_CS_functions.md | 2 +- docs/src/fmi3_lowlevel_ME_functions.md | 7 +- docs/src/fmi3_lowlevel_library_constants.md | 64 +++++++++++- docs/src/fmi3_lowlevel_library_functions.md | 47 ++++----- docs/src/fmi3_lowlevel_library_types.md | 37 ------- ...mi3_lowlevel_modeldescription_functions.md | 26 +---- docs/src/fmi_lowlevel_library_constants.md | 13 +++ docs/src/fmi_lowlevel_library_functions.md | 44 ++++++++- docs/src/fmi_lowlevel_library_types.md | 11 --- ...fmi_lowlevel_modeldescription_functions.md | 98 +++++++++++++++++++ docs/src/library.md | 51 +++++----- 22 files changed, 345 insertions(+), 286 deletions(-) delete mode 100644 docs/src/fmi2_lowlevel_library_types.md delete mode 100644 docs/src/fmi3_lowlevel_library_types.md delete mode 100644 docs/src/fmi_lowlevel_library_types.md create mode 100644 docs/src/fmi_lowlevel_modeldescription_functions.md diff --git a/README.md b/README.md index 90f99ffd..4b64338b 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ | | | |---|---| -| 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) | +| 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://codecov.io/gh/ThummeTo/FMI.jl) | +| 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) 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..13f348ba 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" @@ -36,12 +36,11 @@ makedocs(sitename="FMI.jl", "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 +50,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/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/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 3a316dc7..8677cbc2 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,6 +63,7 @@ The FMU has an internal state consisting of all values that are needed to contin fmi2GetFMUstate fmi2GetFMUstate! fmi2SetFMUstate +fmi2FreeFMUstate fmi2FreeFMUstate! fmi2SerializedFMUstateSize fmi2SerializedFMUstateSize! @@ -83,47 +84,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 -fmi2GetDiscreteStates -fmi2GetDiscreteStates! -fmi2SetDiscreteStates -``` 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 af5dc419..00000000 --- a/docs/src/fmi_lowlevel_library_types.md +++ /dev/null @@ -1,11 +0,0 @@ -# Types in FMI Import/Core .jl - -```@docs -FMU -FMUInstance -FMUSolution -FMUEvent -FMUSnapshot -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 From 59aaef1d5c30df3d7cae696c5bf7265f5c97efac Mon Sep 17 00:00:00 2001 From: Simon Exner <43469235+0815Creeper@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:47:35 +0200 Subject: [PATCH 08/10] Update Example.yml version bump: julia 1.10, dependency actions, removed artifacts, added success check, autocommit for each example --- .github/workflows/Example.yml | 84 +++++++++++++++-------------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/.github/workflows/Example.yml b/.github/workflows/Example.yml index 57eaf579..189ecce6 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,47 @@ 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 }}* - - auto-commit: - needs: sync-files - if: github.event_name != 'pull_request' - runs-on: ubuntu-latest - steps: - - name: Check out repository - uses: actions/checkout@v3 + - name: "run generated jl script to determine success of example building" + run: julia --project=examples/ examples/${{ matrix.file-name }}.jl - - name: Download examples - uses: actions/download-artifact@v3 - with: - name: examples - path: examples/src/ - - - name: auto-commit + - 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: 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/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 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: jupyter + if: github.event_name != 'pull_request' && github.branch == 'main' runs-on: ubuntu-latest steps: # Trigger an repoisitory dispath event From 6ae49966056203d1ea5c86210aadc7c785b35ac1 Mon Sep 17 00:00:00 2001 From: Simon Exner <43469235+0815Creeper@users.noreply.github.com> Date: Fri, 23 Aug 2024 15:37:16 +0200 Subject: [PATCH 09/10] minor doc fixes --- docs/src/fmi2_lowlevel_library_functions.md | 1 - examples/src/simulate.ipynb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/src/fmi2_lowlevel_library_functions.md b/docs/src/fmi2_lowlevel_library_functions.md index 8677cbc2..548764fc 100644 --- a/docs/src/fmi2_lowlevel_library_functions.md +++ b/docs/src/fmi2_lowlevel_library_functions.md @@ -64,7 +64,6 @@ fmi2GetFMUstate fmi2GetFMUstate! fmi2SetFMUstate fmi2FreeFMUstate -fmi2FreeFMUstate! fmi2SerializedFMUstateSize fmi2SerializedFMUstateSize! fmi2SerializeFMUstate 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", From d2e04312e96433bd690837d174ad0d74479348cf Mon Sep 17 00:00:00 2001 From: Simon Exner <43469235+0815Creeper@users.noreply.github.com> Date: Sun, 25 Aug 2024 12:43:31 +0200 Subject: [PATCH 10/10] added pluto examples to CI --- .github/workflows/Example.yml | 47 +++++++++++++++++++++++++++++++++- docs/make.jl | 1 + docs/src/examples/workshops.md | 4 +++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 docs/src/examples/workshops.md diff --git a/.github/workflows/Example.yml b/.github/workflows/Example.yml index 189ecce6..aa85cfec 100644 --- a/.github/workflows/Example.yml +++ b/.github/workflows/Example.yml @@ -81,9 +81,54 @@ jobs: 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" + uses: actions/checkout@v3 + + - name: "Set up Julia" + uses: julia-actions/setup-julia@v1 + with: + 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: pluto-examples[${{ 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 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: jupyter + needs: [jypiter, pluto] if: github.event_name != 'pull_request' && github.branch == 'main' runs-on: ubuntu-latest steps: diff --git a/docs/make.jl b/docs/make.jl index 13f348ba..777c4d27 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -32,6 +32,7 @@ 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[ 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