Code Monkey home page Code Monkey logo

omjulia.jl's Introduction

OpenModelica License: OSMC-PL

OpenModelica is an open-source Modelica-based modeling and simulation environment intended for industrial and academic usage.

OpenModelica User's Guide

The User's Guide is automatically generated from the documentation repository.

OpenModelica environment

The OpenModelica Compiler is the core of the OpenModelica project. OMEdit is the graphical user interface on top of the compiler. OMSimulator is a capable FMI and SSP-based Co-Simulation environment, available as a standalone version or integrated in OMEdit. In addition there are interactive environments OMNotebook, OMPlot and OMShell interaction with the OMCompiler as well as various other tools: OMOptim, OMParser, OMSens, OMSense_Qt.

Working with the repository

OpenModelica.git is a superproject. Clone the project using one of:

# Faster pulling by using openmodelica.org read-only mirror (low latency in Europe; very important when updating all submodules)
# Replace the openmodelica.org pull URL with https://github.com/OpenModelica/OpenModelica.git if you want to pull directly from github
# The default choice is to push to your fork on github.com (SSH). Replace MY_FORK with OpenModelica to push directly to the OpenModelica repositories (if you have access)
MY_FORK=<MyGitHubUserName>
git clone --recurse-submodules https://openmodelica.org/git-readonly/OpenModelica.git
cd OpenModelica
git remote set-url --push origin [email protected]:$MY_FORK/OpenModelica.git
git submodule foreach --recursive 'git remote set-url --push origin `git config --get remote.origin.url | sed s,^.*/,[email protected]:'$MY_FORK'/,`'

If you are a developer and want to update your local git repository to the latest developments or latest heads, use:

# After cloning
cd OpenModelica
git checkout master
git pull
# To checkout the latest master on each submodule run
# you will need to merge each submodule, but your changes will remain
git submodule foreach --recursive "git checkout master && git pull"

# Running master on all submodules might lead to build errors
# so use this to make sure you force all submodules to the commits
# from the OpenModelica glue project which are properly tested
git submodule update --force --init --recursive

In order to push to the repository, you will push to your own fork of OpenModelica.git, etc. You will need to create a fork of each repository that you want to push to (by clicking the Fork button in the GitHub web interface).

If you do not checkout the repositories for some GUI clients (such as OMOptim.git), these directories will be ignored by autoconf and skipped during compilation.

To checkout a specific version of OpenModelica, say tag v1.16.2 do:

git clone --recurse-submodules https://github.com/OpenModelica/OpenModelica.git
cd OpenModelica
git checkout v1.16.2
git submodule update --force --init --recursive

If you have issues building you can try to clean and reset the repository using:

git clean -fdx
git submodule foreach --recursive git clean -fdx
git reset --hard
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive

To check your working copy status and the hashes of the submodules, use:

git status
git submodule status --recursive

To checkout a minimal version of OpenModelica

git clone https://openmodelica.org/git-readonly/OpenModelica.git OpenModelica-minimal
cd OpenModelica-minimal
git submodule update --init --recursive libraries

Build OpenModelica

We automatically generate nightly builds for Windows and for various flavours of Linux. You can download and install them directly if you just want to run the latest development version of OpenModelica without the effort of compiling the sources yourself.

How to run

Here is a short example session. This example uses OMShell-terminal, but OMShell, mos-scripts, or OMNotebook work the same way.

$ cd trunk/build/bin
$ ./OMShell-terminal
OMShell Copyright 1997-2015, Open Source Modelica Consortium (OSMC)
Distributed under OMSC-PL and GPL, see www.openmodelica.org

To get help on using OMShell and OpenModelica, type "help()" and press enter
Started server using:omc -d=interactive > /tmp/omshell.log 2>&1 &
>>> loadModel(Modelica)
true
>>> getErrorString()
""
>> instantiateModel(Modelica.Electrical.Analog.Basic.Resistor)
"class Modelica.Electrical.Analog.Basic.Resistor \"Ideal linear electrical resistor\"
  Real v(quantity = \"ElectricPotential\", unit = \"V\") \"Voltage drop between the two pins (= p.v - n.v)\";
  Real i(quantity = \"ElectricCurrent\", unit = \"A\") \"Current flowing from pin p to pin n\";
  Real p.v(quantity = \"ElectricPotential\", unit = \"V\") \"Potential at the pin\";
  Real p.i(quantity = \"ElectricCurrent\", unit = \"A\") \"Current flowing into the pin\";
  Real n.v(quantity = \"ElectricPotential\", unit = \"V\") \"Potential at the pin\";
  Real n.i(quantity = \"ElectricCurrent\", unit = \"A\") \"Current flowing into the pin\";
  parameter Boolean useHeatPort = false \"=true, if HeatPort is enabled\";
  parameter Real T(quantity = \"ThermodynamicTemperature\", unit = \"K\", displayUnit = \"degC\", min = 0.0, start = 288.15, nominal = 300.0) = T_ref \"Fixed device temperature if useHeatPort = false\";
  Real LossPower(quantity = \"Power\", unit = \"W\") \"Loss power leaving component via HeatPort\";
  Real T_heatPort(quantity = \"ThermodynamicTemperature\", unit = \"K\", displayUnit = \"degC\", min = 0.0, start = 288.15, nominal = 300.0) \"Temperature of HeatPort\";
  parameter Real R(quantity = \"Resistance\", unit = \"Ohm\", start = 1.0) \"Resistance at temperature T_ref\";
  parameter Real T_ref(quantity = \"ThermodynamicTemperature\", unit = \"K\", displayUnit = \"degC\", min = 0.0, start = 288.15, nominal = 300.0) = 300.15 \"Reference temperature\";
  parameter Real alpha(quantity = \"LinearTemperatureCoefficient\", unit = \"1/K\") = 0.0 \"Temperature coefficient of resistance (R_actual = R*(1 + alpha*(T_heatPort - T_ref))\";
  Real R_actual(quantity = \"Resistance\", unit = \"Ohm\") \"Actual resistance = R*(1 + alpha*(T_heatPort - T_ref))\";
equation
  assert(1.0 + alpha * (T_heatPort - T_ref) >= 1e-15, \"Temperature outside scope of model!\");
  R_actual = R * (1.0 + alpha * (T_heatPort - T_ref));
  v = R_actual * i;
  LossPower = v * i;
  v = p.v - n.v;
  0.0 = p.i + n.i;
  i = p.i;
  T_heatPort = T;
  p.i = 0.0;
  n.i = 0.0;
end Modelica.Electrical.Analog.Basic.Resistor;
"
>> a:=1:5;
>> b:=3:8
{3,4,5,6,7,8}
>>> a*b

>>> getErrorString()
"[<interactive>:1:1-1:0:writable] Error: Incompatible argument types to operation scalar product in component <NO COMPONENT>, left type: Integer[5], right type: Integer[6]
[<interactive>:1:1-1:0:writable] Error: Incompatible argument types to operation scalar product in component <NO COMPONENT>, left type: Real[5], right type: Real[6]
[<interactive>:1:1-1:0:writable] Error: Cannot resolve type of expression a * b. The operands have types Integer[5], Integer[6] in component <NO COMPONENT>.
"
>> b:=3:7;
>> a*b
85
>>> listVariables()
{b, a}
>>

How to contribute to the OpenModelica Compiler

The long-term development of OpenModelica is supported by a non-profit organization - the Open Source Modelica Consortium (OSMC).

See CONTRIBUTING.md on how to contribute to the development. If you encounter any bugs, feel free to open a ticket about it. For general questions regarding OpenModelica there is a discussions section available.

License

See OSMC-License.txt.

How to cite

See the CITATIONS file for information on how to cite OpenModelica in any publications reporting work done using OpenModelica. For a complete list of all publications related to OpenModelica see doc/bibliography/openmodelica.bib.


Last updated: 2023-06-21

omjulia.jl's People

Contributors

adrpo avatar anheuermann avatar arun3688 avatar casella avatar chrbertsch avatar christiankral avatar dilumaluthge avatar jkrt avatar sjoelund avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

omjulia.jl's Issues

OMJulia scripting api docu: link to OMJulia functions

The scripting api gives not indication whether the function has to be called as string argument or if there is a convenience function available.

It would be great if the api functions were providing links the julia functions, if they exist.

Also it would be helpful if there were references from the OMJulia Sensitivity Analysis paragraph, which is just explaining the syntax, to the parameter sensitivity section, which explains the mathematical background.

Appetite to wrap the scripting api?

When using OMPython previously I spent some time wrapping it in less-primitive functions:

    def loadFile(self, filePath): #load some other *.mo file, True = load success, False = failed
        relPath = self.getRelativePathFromWorkingDirectory( filePath ) #file path must be RELATIVE to Modelica's working directory, absolute do not work
        if relPath:
            ret = self.omc.sendExpression('loadFile("./{0}")'.format( relPath ) )
            if not ret:
                print('Modelica.loadFile(): on filePath[' + filePath +'] relPath[' + relPath +'] returned',ret)
        else:
            print('loadFile: relPath failed', relPath)
            ret = False

        if ret is False :
            print('loadFile [' + filePath +'] failed')

        return ret

This is needed because the zeroMQ / sendExpression interface lacks error handling. While it would be useful for omc to be more verbose (and documented!), a wrapper can smooth over the rough edges. I can make a longer proposal if desired.

Is there any appetite/roadmap to include those functions within OMJulia or should I again keep these separate? Similarly, I wrote a pr for MAT.jl to read Modelica mat files, but that function could be placed here just as well in my opinion.

Thoughts?

Call command shell on windows using API.system

I'd want to copy the result file to a new loaction and tried the following:

sendExpression(omc,"system(\"copy model_res.csv model_ref.csv)")

and got

ERROR: OMJulia.Parser.LexerError("Error while lexing")
Stacktrace:
 [1] tokenize(data::String)
   @ OMJulia.Parser C:\Users\leo2rng\.julia\packages\OMJulia\ZS3rq\src\lexer.jl:172
 [2] parseOM
   @ C:\Users\leo2rng\.julia\packages\OMJulia\ZS3rq\src\parser.jl:127 [inlined]
 [3] sendExpression(omc::OMJulia.OMCSession, expr::String; parsed::Bool)
   @ OMJulia C:\Users\leo2rng\.julia\packages\OMJulia\ZS3rq\src\sendExpression.jl:85
 [4] sendExpression(omc::OMJulia.OMCSession, expr::String)
   @ OMJulia C:\Users\leo2rng\.julia\packages\OMJulia\ZS3rq\src\sendExpression.jl:74

The command copy model_res.csv model_ref.csv executed in a windows cmd shell works. Why not using system()?

Set methods dictionary input

For the set methods documented in https://openmodelica.github.io/OMJulia.jl/dev/modelicaSystem/#Set-Methods

Two setting possibilities are accepted using setXXXs(),where "XXX" can be any of above functions.

  1. setXXX("Name=value") string of keyword assignments
  2. setXXX(["Name1=value1","Name2=value2","Name3=value3"]) array of string of keyword assignments

having tuples of names and values as string or array of strings is a bit strange.

I suggest to add higher level methods for the set methods with dictionaries instead of a list of strings

parameters = Dict("x"=>1, "y"=>7.0, "z"=>"hello")
setParameters(omc, parameters)

function setParameters(omc, parameters::Dict{Any}, verbose::Bool = true)
  name = ["$(p[1])=$(p[2])" for p in collect(parameters)]
  setParameters(omc, name, verbose)
end

How to handle structural change of models

Modelica model

Consider the following Modelica model which incorporates a structural change (number of states) depending on the integer parameter dyn:

model Test
  parameter Integer dyn = 1;
  parameter Real c = 1;
  Real x(start = c);
equation
  if dyn == 1 then
    der(x) = -c * x;
  else
    x = c;
  end if;
end Test;

Case 1: Simulate model with dyn = 1

The default value is dyn = 1, so the parameter does not have to be changed for Case 1. I run the following code in Julia:

using OMJulia
mod = OMJulia.OMCSession()
ModelicaSystem(mod, "Test.mo", "Test")
simulate(mod)
dyn = getParameters(mod, "dyn")
x = getSolutions(mod, "x")[end][end]
println("dyn  = ", dyn, "\tx = ", x)

The result is dyn = 1 x = 0.3678794515339768 as expected.

Case 2: Simulate model with dyn = 0

Now I want to change the structure of the model by setting dyn = 0. This implies that the number of states changes.

Reading the documentation at https://www.openmodelica.org/doc/OpenModelicaUsersGuide/latest/omjulia.html shows:

image

but the following code does not:

setParameters(mod,"dyn=0")
OMJulia.buildModel(mod)
simulate(mod)
dyn = getParameters(mod, "dyn")
x = getSolutions(mod, "x")[end][end]
println("dyn  = ", dyn, "\tx = ", x)

Again the result dyn = 1 x = 0.3678794515339768 is the same as before. So obviously, the parameter dyn was NOT changed. Why?

Case 1 and Case 2 together are stored in file Test.jl.zip

get functions broken

The functions getContinuous and getInputs seem to be broken.

In the generated documentation the return only "None":

julia> getInputs(mod)
Dict{Any, Any} with 4 entries:
  "Ti"  => "None"
  "cAi" => "None"
  "Vdi" => "None"
  "Tc"  => "None"


julia> getOutputs(mod)
Dict{Any, Any} with 1 entry:
  "y_T" => "None"

We should add a unit test for these API functions.

Custom omc path on windows

I want to be able to use a specific omc executable in a OMCSession and to be able to use different executables at the same time.

I would like to do something like:

omc_1 = OMJulia.OMCSession()  # omc from OPENMODELICAHOME environment variable
omc_2 = OMJulia.OMCSession("D://workspace//OpenModelica//build//bin//omc.exe")  # omc specified with path to executable

OpenModelica compiled with UCRT can't build model

Description

I can't compile Modelica models with OMJulia.jl.

How to reproduce

Build OpenModelica with Universal C runtime (UCRT) following https://github.com/AnHeuermann/OpenModelica/blob/msys2-ucrt64/OMCompiler/README.Windows.md#13-install-msys2. (This might become the default to build OpenModelica soon.)

Then start Julia from e.g. PowerShell and run:

using OMJulia

pathToOmc = "path\\to\\OpenModelica\\build_cmake\\install_cmake\\bin\\omc.exe"
omc=OMJulia.OMCSession(pathToOmc)

msg = sendExpression(omc, "getVersion()")
@info msg
sendExpression(omc, "loadModel(Modelica)")
msg = sendExpression(omc, "buildModel(Modelica.Electrical.Analog.Examples.CauerLowPassAnalog)")
@info msg
msg = sendExpression(omc, "getErrorString()")
@info msg
[ Info: Setting environment variable OPENMODELICAHOME="D:\workspace\OM\OpenModelica\build_cmake\install_cmake" for this session.
[ Info: Path to zmq file="C:\Users\AHEUER~1\AppData\Local\Temp\openmodelica.port.julia.mm9RDN43qR"
[ Info: v1.22.0-dev-262-gdbaa7ffa95-cmake
[ Info: ["", ""]
┌ Info: Error: Error building simulator. Build log: Das System kann den angegebenen Pfad nicht finden.
│ Das System kann den angegebenen Pfad nicht finden.
└ RESULT: 3

Translation: The system can't find the specified path. Result 3.

Starting Julia from OMDev bash fixes the issue, because the msys tools are in PATH.

Version

  • OS: Windows 11
  • OMDev: UCRT64 environment instead of the default MINGW64 environment
  • Julia Version 1.9.2
  • OMJulia @67f69adb6dfc711402e08ed5feb87983796d4475

Getting a bunch of temp dirs

When creating some OMJulia.OMCSessions my directory ends up containng a bunch of empty directories starting with zz_.

We should delete the empty directory after everything is done. Also I can't see if anything is done in the zz_ directory.
omc.tempdir has always a different string.

Test Julia LTS and stable version

The Jenkinsfile is using docker.openmodelica.org/omjulia-build-deps:v0.1.0 where Julia v1.0.3 is installed.
The current LTS (1.6.7) and stable (v1.8.2) versions should also be tested.

Both could be added to the Dockerfile and two more stages can be added to the Jenkins pipeline. But then someone has to keep track of what is the current stable / LTS version and update the Jenkinsfile.

It is also possible to use a GitHub workflow on a Docker image with OpenModelica and add the setup-julia action to it.

Closing of OMCSession

When I run perform batch processes based on OMJulia, several hundret calls of OMCSession are performed.

image

After that I have many abandonded processes which push the RAM consumption of my (Linux) computer to its limits.

I could neither find in the documentation nor in the examples, how I can free the memory resources by closing the used OMCSession. My question thus refers to an equivalence of close, used after openening and writing a file. Is such closing alread implemented? If not, it possibly should be implemented.

(@v1.10) pkg> test OMJulia fails

Executing test OMJulia fails ::

[2] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:84 [inlined]
[3] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[4] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:66 [inlined]
[5] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[6] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:33
Multiple sessions: Test Failed at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:86
Expression: isfile(joinpath(#= C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:86 =# @DIR(), "test-omc1", "Modelica.Blocks.Examples.PID_Controller_res.mat"))

Stacktrace:
[1] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:672 [inlined]
[2] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:86 [inlined]
[3] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[4] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:66 [inlined]
[5] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[6] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:33
Multiple sessions: Test Failed at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:89
Expression: true == OMJulia.sendExpression(omc2, "loadModel(Modelica)")
Evaluated: true == false

Stacktrace:
[1] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:672 [inlined]
[2] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:89 [inlined]
[3] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[4] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:66 [inlined]
[5] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[6] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:33
Multiple sessions: Test Failed at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:91
Expression: isfile(joinpath(#= C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:91 =# @DIR(), "test-omc2", "Modelica.Blocks.Examples.PID_Controller_res.mat"))

Stacktrace:
[1] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:672 [inlined]
[2] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:91 [inlined]
[3] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[4] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:66 [inlined]
[5] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[6] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\omcTest.jl:33
[ Info: Path to zmq file="C:\Users\Denis\AppData\Local\Temp\openmodelica.port.julia.yJFvO5btut"
ModelicaSystem: Error During Test at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\modelicaSystemTest.jl:32
Got exception outside of a @test
[C:/Program Files/OpenModelica1.22.1-64bit/share/omlibrary/cache/index.json:0:0-0:0:readonly] Notification: Cached libraries were found and will be installed into C:/Users/Denis/AppData/Roaming/.openmodelica/libraries/.
Error: Failed to open file: C:/Users/Denis/AppData/Roaming/.openmodelica/cache/c11123102e94d4b5acb139331a6d85f45d8adcc0.zip
Notification: After extracting C:/Users/Denis/AppData/Roaming/.openmodelica/cache/c11123102e94d4b5acb139331a6d85f45d8adcc0.zip, C:/Users/Denis/AppData/Roaming/.openmodelica/libraries/Complex 4.0.0+maint.om/package.mo does not exist. Removing the failed installation.

Stacktrace:
[1] error(s::String)
@ Base .\error.jl:35
[2] loadFile(omc::OMJulia.OMCSession, filename::String)
@ OMJulia C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\modelicaSystem.jl:167
[3] ModelicaSystem(omc::OMJulia.OMCSession, fileName::String, modelName::String, library::Nothing; commandLineOptions::Nothing, variableFilter::Nothing)
@ OMJulia C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\modelicaSystem.jl:93
[4] ModelicaSystem
@ OMJulia C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\modelicaSystem.jl:71 [inlined]
[5] ModelicaSystem(omc::OMJulia.OMCSession, fileName::String, modelName::String)
@ OMJulia C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\modelicaSystem.jl:71
[6] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\modelicaSystemTest.jl:40 [inlined]
[7] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[8] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\modelicaSystemTest.jl:33
[9] include(mod::Module, _path::String)
@ Base .\Base.jl:495
[10] include(x::String)
@ Main.var"##ModelicaSystem#227" C:\Users\Denis.julia\packages\SafeTestsets\raUNr\src\SafeTestsets.jl:28
[11] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:35 [inlined]
[12] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[13] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:35 [inlined]
[14] top-level scope
@ C:\Users\Denis.julia\packages\SafeTestsets\raUNr\src\SafeTestsets.jl:30
[15] eval(m::Module, e::Any)
@ Core .\boot.jl:385
[16] macro expansion
@ C:\Users\Denis.julia\packages\SafeTestsets\raUNr\src\SafeTestsets.jl:28 [inlined]
[17] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:35 [inlined]
[18] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[19] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:33
[20] include(fname::String)
@ Base.MainInclude .\client.jl:489
[21] top-level scope
@ none:6
[22] eval
@ Core .\boot.jl:385 [inlined]
[23] exec_options(opts::Base.JLOptions)
@ Base .\client.jl:291
[24] _start()
@ Base .\client.jl:552
[ Info: Path to zmq file="C:\Users\Denis\AppData\Local\Temp\openmodelica.port.julia.yJFvO5btut"
API: Error During Test at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:43
Test threw exception
Expression: OMJulia.API.loadFile(omc, joinpath(#= C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:43 =# @DIR(), "../docs/testmodels/BouncingBall.mo"))
Failed to load file "C:/Users/Denis/.julia/packages/OMJulia/ZS3rq/test/../docs/testmodels/BouncingBall.mo".
[C:/Program Files/OpenModelica1.22.1-64bit/share/omlibrary/cache/index.json:0:0-0:0:readonly] Notification: Cached libraries were found and will be installed into C:/Users/Denis/AppData/Roaming/.openmodelica/libraries/.
Error: Failed to open file: C:/Users/Denis/AppData/Roaming/.openmodelica/cache/c11123102e94d4b5acb139331a6d85f45d8adcc0.zip
Notification: After extracting C:/Users/Denis/AppData/Roaming/.openmodelica/cache/c11123102e94d4b5acb139331a6d85f45d8adcc0.zip, C:/Users/Denis/AppData/Roaming/.openmodelica/libraries/Complex 4.0.0+maint.om/package.mo does not exist. Removing the failed installation.

Stacktrace:
[1] loadFile(omc::OMJulia.OMCSession, fileName::String; encoding::String, uses::Bool, notify::Bool, requireExactVersion::Bool)
@ OMJulia.API C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\api.jl:130
[2] loadFile(omc::OMJulia.OMCSession, fileName::String)
@ OMJulia.API C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\api.jl:118
[3] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:43 [inlined]
[4] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:669 [inlined]
[5] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:43 [inlined]
[6] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[7] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:35
API: Test Failed at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:52
Expression: result[2] == "BouncingBall_init.xml"
Evaluated: "" == "BouncingBall_init.xml"

Stacktrace:
[1] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:672 [inlined]
[2] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:52 [inlined]
[3] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[4] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:35
API: Error During Test at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:34
Got exception outside of a @test
Failed to simulate BouncingBall.
Simulation Failed. Model: BouncingBall does not exist! Please load it first before simulation.
[C:/Program Files/OpenModelica1.22.1-64bit/share/omlibrary/cache/index.json:0:0-0:0:readonly] Notification: Cached libraries were found and will be installed into C:/Users/Denis/AppData/Roaming/.openmodelica/libraries/.
Error: Failed to open file: C:/Users/Denis/AppData/Roaming/.openmodelica/cache/c11123102e94d4b5acb139331a6d85f45d8adcc0.zip
Notification: After extracting C:/Users/Denis/AppData/Roaming/.openmodelica/cache/c11123102e94d4b5acb139331a6d85f45d8adcc0.zip, C:/Users/Denis/AppData/Roaming/.openmodelica/libraries/Complex 4.0.0+maint.om/package.mo does not exist. Removing the failed installation.

Stacktrace:
[1] simulate(omc::OMJulia.OMCSession, className::String; startTime::Float64, stopTime::Nothing, numberOfIntervals::Int64, tolerance::Float64, method::String, fileNamePrefix::String, options::String, outputFormat::String, variableFilter::String, cflags::String, simflags::String)
@ OMJulia.API C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\api.jl:214
[2] simulate(omc::OMJulia.OMCSession, className::String)
@ OMJulia.API C:\Users\Denis.julia\packages\OMJulia\ZS3rq\src\api.jl:180
[3] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:61 [inlined]
[4] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[5] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\apiTest.jl:35
[6] include(mod::Module, _path::String)
@ Base .\Base.jl:495
[7] include(x::String)
@ Main.var"##API#228" C:\Users\Denis.julia\packages\SafeTestsets\raUNr\src\SafeTestsets.jl:28
[8] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:36 [inlined]
[9] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[10] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:36 [inlined]
[11] top-level scope
@ C:\Users\Denis.julia\packages\SafeTestsets\raUNr\src\SafeTestsets.jl:30
[12] eval(m::Module, e::Any)
@ Core .\boot.jl:385
[13] macro expansion
@ C:\Users\Denis.julia\packages\SafeTestsets\raUNr\src\SafeTestsets.jl:28 [inlined]
[14] macro expansion
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:36 [inlined]
[15] macro expansion
@ C:\Users\Denis.julia\juliaup\julia-1.10.0+0.x64.w64.mingw32\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
[16] top-level scope
@ C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:33
[17] include(fname::String)
@ Base.MainInclude .\client.jl:489
[18] top-level scope
@ none:6
[19] eval
@ Core .\boot.jl:385 [inlined]
[20] exec_options(opts::Base.JLOptions)
@ Base .\client.jl:291
[21] _start()
@ Base .\client.jl:552
Test Summary: | Pass Fail Error Total Time
OMJulia | 26 8 3 37 10.9s
Parsing | 19 19 2.7s
OMCSession | 4 7 11 3.6s
OpenModelica | 4 7 11 3.5s
OMCSession | 4 3 7 2.8s
Multiple sessions | 4 4 0.7s
ModelicaSystem | 1 1 1.9s
ModelicaSystem | 1 1 1.9s
API | 3 1 2 6 2.6s
API | 3 1 2 6 2.4s
ERROR: LoadError: Some tests did not pass: 26 passed, 8 failed, 3 errored, 0 broken.
in expression starting at C:\Users\Denis.julia\packages\OMJulia\ZS3rq\test\runtests.jl:32
ERROR: Package OMJulia errored during testing

(@v1.10) pkg>

Kill dangling omc process

When a OMCSession isn't quit the omc process stays running forever.

Maybe finalizer is an option to kill the omc process when the memory for OMCSession is no longer accessible.

Multi-threading with OMJulia

Hi there! I am using OMJulia in VSCode and am trying to optimise the parameters of dynamic Modelica models.

I was wondering if the multi-threading of simulations is possible with OMJulia? I have tried creating multiple OMCSession objects and running parallel simulations across them but I get a "TaskFailedException" as soon as multiple simulations try to run at once. I am quite new to both OMJulia and multi-threading so I'm not sure if this is a limitation of OMJulia or a mistake on my end.

ProcessFailedException when using ModelicaSystem

If I directly use loadFile(), loadModel(), buildModel(), and simulate() via sendExpression, I can simulate this model without problem, but using ModelicaSystem()/buildModel/simulate leads to a ProcessFailed exception:
caught error[ProcessFailedException(Base.Process[Process(`'C:/Users/BENCON~1/AppData/Local/Temp/jl_nFAMOr/FallingModel.exe'`, ProcessExited(3221225785))])]

where I've wrapped the simulate() in a try/catch:

modelText = """model FallingModel
  inner Modelica.Mechanics.MultiBody.World world;
  Modelica.Mechanics.MultiBody.Joints.FreeMotion freeMotion(animation = false,r_rel_a(start = {1, 0, 0}), w_rel_a_fixed = true, w_rel_a_start = {1, 2, 3});
  Modelica.Mechanics.MultiBody.Parts.Body body(animation = true,m = 1, r_0(start = {1, 0, 0}));
equation
  connect(world.frame_b, freeMotion.frame_a);
  connect(freeMotion.frame_b, body.frame_a);
  annotation( uses(Modelica(version = "4.0.0")));
end FallingModel;
"""
modelPath = "./FallingModel.mo"
modelName = "FallingModel"

write("FallingModel.mo", modelText)

omc = OMJulia.OMCSession()
try
  OMJulia.ModelicaSystem(omc, modelPath, modelName)
  OMJulia.buildModel(omc) 
  OMJulia.simulate(omc)
catch e
  println("\ncaught error[$e]\n")
  ges = OMJulia.sendExpression(omc, "getErrorString()") 
  println("getErrorString()=$ges")
  dump(omc)
finally
  OMJulia.sendExpression(omc, "quit()", parsed=false)
end

see attached console output.

I suspect the problem is in an argument added to omc by ModelicaSystem/later, but nothing is jumping out at me. I will note that the self-assembled omc is about half of the size as the one made by ModelicaSystem.

Thanks

Upgrade lexer to Automa.jl v1.0

Description

The lexer lexer.jl was generated with Julia v.16 (or lower) and Automa.jl v0.7 (or something around that version).

We should update to Automa.jl v1 and add a workflow to check if lexer.jl is up to date.

Related issues

To update the lexer for #123 we should update Automa.jl.

setSimulationOptions keyword argumente inputs

The input name or setSimulationOptions is difficult to use and error prone.

Two setting possibilities are accepted using setXXXs(),where "XXX" can be any of above functions.

  1. setXXX("Name=value") string of keyword assignments
  2. setXXX(["Name1=value1","Name2=value2","Name3=value3"]) array of string of keyword assignments

There are only four simulation options one can set.

Make them keyword arguments of setSimulationOptions:

function setSimulationOptions(omc; startTime, stopTime, interval, tolerance)

and give them default values (e.g. nothing).

Debugging Julia with OMJulia gives ZMQ.StateError

Description

I'm using VS Code and the Julia extension to debug my Julia projects.
When debugging code that also uses OMJulia I'm hitting errors I don't see when running the code without the debugger.

How to reproduce

When starting to debug a file with

using OMJulia
using OMJulia: sendExpression

omc = OMCSession()
sendExpression(omc, "loadModel(Modelica)")
sendExpression(omc, "simulate(Modelica.Electrical.Analog.Examples.CauerLowPassAnalog)")
sendExpression(omc, "quit()", parsed=false)

@error "Try to break before you hit me!"

I'm hitting an error in ZMQ.jl package:

Exception has occurred: ZMQ.StateError
ZMQ.StateError("Success")

Stacktrace:
 [1] _recv!(socket::ZMQ.Socket, zmsg::ZMQ.Message)
   @ ZMQ ~/.julia/packages/ZMQ/R3wSD/src/comm.jl:73
 [2] recv(socket::ZMQ.Socket)
   @ ZMQ ~/.julia/packages/ZMQ/R3wSD/src/comm.jl:94
 [3] sendExpression(omc::OMJulia.OMCSession, expr::String; parsed::Bool)
   @ OMJulia ~/workdir/julia/OMJulia.jl/src/OMJulia.jl:183
 [4] sendExpression(omc::OMJulia.OMCSession, expr::String)
   @ OMJulia ~/workdir/julia/OMJulia.jl/src/OMJulia.jl:180
 [5] top-level scope
   @ ~/workdir/julia/OMJulia.jl/bug.jl:6

I'm not sure if this is a ZMQ problem or the omc.socket from OMJulia is different when I'm debugging.

Without debugging

omc.socket = ZMQ.Socket(Ptr{Nothing} @0x0000000003818660, FileWatching._FDWatcher(Ptr{Nothing} @0x0000000003b9c910, 35, (1, 0), Base.GenericCondition{Base.Threads.SpinLock}(Base.InvasiveLinkedList{Task}(nothing, nothing), Base.Threads.SpinLock(0)), 0, (false, false)))

with debugging

omc.socket = ZMQ.Socket(Ptr{Nothing} @0x000000000305cce0, FileWatching._FDWatcher(Ptr{Nothing} @0x0000000002a8a950, 34, (1, 0), Base.GenericCondition{Base.Threads.SpinLock}(Base.InvasiveLinkedList{Task}(nothing, nothing), Base.Threads.SpinLock(0)), 0, (false, false)))

Versions 'n stuff

  • OS: Ubuntu Focal
  • julia> versioninfo()
    Julia Version 1.8.1
    Commit afb6c60d69a (2022-09-06 15:09 UTC)
    Platform Info:
      OS: Linux (x86_64-linux-gnu)
      CPU: 48 × Intel(R) Xeon(R) Gold 6248R CPU @ 3.00GHz
      WORD_SIZE: 64
      LIBM: libopenlibm
      LLVM: libLLVM-13.0.1 (ORCJIT, cascadelake)
      Threads: 1 on 48 virtual cores
  • OMJulia v0.2.0 @d1e889924f0940dc9bbbc0bd13f676b1cb297151

OMJulia "simulate()" does not work with OMC v1.17.0

OMJulia v0.1.0 was tested before with OpenModelica v1.16.X and work fine, but now it does not work with OM compiler v1.17.0
"getX" and "setX" methos are ok but "simulate()" fails

Example of the error message:
ERROR: LoadError: failed process: Process(C:/Users/victo/AppData/Local/Temp/jl_c4ikD7/SisHidraTk1e.exe, ProcessExited(3221225781)) [3221225781]

Stacktrace:
[1] pipeline_error at .\process.jl:525 [inlined]
[2] #run#565(::Bool, ::typeof(run), ::Base.CmdRedirect) at .\process.jl:440
[3] run at .\process.jl:438 [inlined]
[4] (::OMJulia.var"#24#73"{OMJulia.OMCSession})() at C:\Users\victo.julia\packages\OMJulia\ZLXEs\src\OMJulia.jl:450
[5] top-level scope at C:\Users\victo\OneDrive\Documentos\J-OMJulia\SisHidraTk1e_omj.jl:21
in expression starting at C:\Users\victo\OneDrive\Documentos\J-OMJulia\SisHidraTk1e_omj.jl:21

Following messages are displayed in all cases:
[1] pipeline_error at .\process.jl:525 [inlined]
[2] #run#565(::Bool, ::typeof(run), ::Base.CmdRedirect) at .\process.jl:440
[3] run at .\process.jl:438 [inlined]

----

Same Modelica models simulatios were made using OMPython and OpenModelica v1.17.0 and have no errors.

OMJulia api docu: sample code should work right away

The introduction to OMJulia is nice but still not straight forward with stumbling blocks for new users.
For instance the example code:

using OMJulia
mod = OMJulia.OMCSession()
ModelicaSystem(mod,"BouncingBall.mo","BouncingBall")

doesn't work unless you have the mo file in the proper place.

A new user should be able to run the code just like that.
I'd suggest to provide the required models for download or use a model from the MSL and document all prerequisites, like path to the MSL and so on, such that everybody is able to reproduce the results without being confronted with error messages after executing the code examples and having to trouble shoot all kind of things (e.g. figure out the path to the MSL) that could be easily documented or integrated in the code.

Cannot set parameter in a class being extended

Consider the following example and store it as Test.mo:

package Test

    model Example
        extends Test.Data;
        Real x(start = c);
    equation
        if dyn == 1 then
            der(x) = -c * x;
        else
            x = c;
        end if;
    end Example;
  
    model Data
        parameter Integer dyn = 1;
        parameter Real c = 1;
    equation
    end Data;
  
end Test;

The parameters dyn and c are declared in the model Test.Data which is extended in Test.Example.

When running the following Julia script I run into issues:

using OMJulia
mod = OMJulia.OMCSession()
ModelicaSystem(mod, "Test.mo", "Test.Example")
getParameters(mod)
# The following line DOES NOT WORK
sendExpression(mod, "setParameterValue(Test.Example, c, 9)")
# The following line DOES WORK and has the intended effect
sendExpression(mod, "setParameterValue(Test.Data, c, 9)")
buildModel(mod)
simulate(mod)
c = getParameters(mod, "c")
x = getSolutions(mod, "x")[end][end]
println("c  = ", c, "\tx = ", x)

Issues

  1. getParameters(mod) shows the following results, which totally makes sense, as c and dyn are parameters of Test.Example:
Dict{Any, Any} with 2 entries:
  "c"   => "1.0"
  "dyn" => "1"
  1. The command sendExpression(mod, "setParameterValue(Test.Example, c, 9)") causes an error for an unknown reason. As the parameter c is shown by getParameters(mod) I would expect setParameters to work properly: but it doesn't. The error message is:
Stacktrace:
 [1] tokenize(data::String)
   @ OMJulia.Parser ~/.julia/packages/OMJulia/qSIBn/src/lexer.jl:172
 [2] parseOM
   @ ~/.julia/packages/OMJulia/qSIBn/src/parser.jl:127 [inlined]
 [3] sendExpression(omc::OMJulia.OMCSession, expr::String; parsed::Bool)
   @ OMJulia ~/.julia/packages/OMJulia/qSIBn/src/OMJulia.jl:184
 [4] sendExpression(omc::OMJulia.OMCSession, expr::String)
   @ OMJulia ~/.julia/packages/OMJulia/qSIBn/src/OMJulia.jl:180
 [5] top-level scope
   @ REPL[70]:2
  1. The workarouind is to set the parameter c in model Data by sendExpression(mod, "setParameterValue(Test.Data, c, 9)"). But is not a good solution as I have to know that the model Test.Data is used in Test.Example. So I have to have knowledge on how the model Test.Example is written in Modelica and that cannot be a good solution.

I think that the error of item 2. is a bug.

Warning: Method definition kwcall overwritten

I installed OMJulia and received this warnings about overwritten methods definition:

Precompiling project...
114 dependencies successfully precompiled in 261 seconds. 199 already precompiled.
1 dependency had warnings during precompilation:
┌ OMJulia [0f4fe800-344e-11e9-2949-fb537ad918e1]
│ WARNING: Method definition ModelicaSystem(OMJulia.OMCSession) in module OMJulia at /home/juanjose/.julia/packages/OMJulia/rKADx/src/modelicaSystem.jl:71 overwritten at /home/juanjose/.julia/packages/OMJulia/rKADx/src/modelicaSystem.jl:138.
│ ** incremental compilation may be fatally broken for this module **

│ WARNING: Method definition kwcall(Any, typeof(OMJulia.ModelicaSystem), OMJulia.OMCSession) in module OMJulia at /home/juanjose/.julia/packages/OMJulia/rKADx/src/modelicaSystem.jl:71 overwritten at /home/juanjose/.julia/packages/OMJulia/rKADx/src/modelicaSystem.jl:138.
│ ** incremental compilation may be fatally broken for this module **

Function defined in Line 71 of modelicaSystem.jl:

function ModelicaSystem(omc::OMCSession,
                        fileName::AbstractString = nothing,
                        modelName::AbstractString = nothing,
                        library::Union{<:AbstractString, Tuple{<:AbstractString, <:AbstractString}, Array{<:AbstractString}, Array{Tuple{<:AbstractString, <:AbstractString}}, Nothing} = no>
                        commandLineOptions::Union{<:AbstractString, Nothing} = nothing,
                        variableFilter::Union{<:AbstractString, Nothing} = nothing)

    ## check for commandLineOptions
    setCommandLineOptions(omc, commandLineOptions)

    ## set default command Line Options for linearization as
    ## linearize() will use the simulation executable and runtime
    ## flag -l to perform linearization
    sendExpression(omc, "setCommandLineOptions(\"--linearizationDumpLanguage=julia\")")
    sendExpression(omc, "setCommandLineOptions(\"--generateSymbolicLinearization\")")

    omc.filepath = fileName
    omc.modelname = modelName
    omc.variableFilter = variableFilter

    #loadFile and set temporary directory
    loadFile(omc, fileName)

    #set temp directory for each modelica session
    setTempDirectory(omc)

    #load Libraries provided by users
    loadLibrary(omc, library)

    # build the model
    buildModel(omc)
end

Function defined in Line 138 of the same file:

function ModelicaSystem(omc::OMCSession;
    modelName::AbstractString=nothing,
    library::Union{<:AbstractString,Tuple{<:AbstractString,<:AbstractString},Array{<:AbstractString},Array{Tuple{<:AbstractString,<:AbstractString}},Nothing}=nothing,
    commandLineOptions::Union{<:AbstractString,Nothing}=nothing,
    variableFilter::Union{<:AbstractString,Nothing}=nothing)

    if isnothing(modelName)
        return println("\"ModelicaSystem()\" constructor requires modelName")
    end

    ## check for commandLineOptions
    setCommandLineOptions(omc, commandLineOptions)

    ## set default command Line Options for linearization as
    ## linearize() will use the simulation executable and runtime
    ## flag -l to perform linearization
    sendExpression(omc, "setCommandLineOptions(\"--linearizationDumpLanguage=julia\")")
    sendExpression(omc, "setCommandLineOptions(\"--generateSymbolicLinearization\")")

    omc.modelname = modelName
    omc.variableFilter = variableFilter

    #set temp directory for each modelica session
    setTempDirectory(omc)

    #load Libraries provided by users
    loadLibrary(omc, library)

    # build the model
    buildModel(omc)
end

OMJulia scripting api docu: No explanations

The scripting API is basically a listing of the syntax of the available functions.
This might be ok, if you're asking: "How to use it?", but it is not very helpful if you asking: "What is it good for?".

For instance, when searching for "directorypath" you find get functions for: WorkingDirectory, HomeDirectory, TempDirectory und InstallationDirectory, but there is no notion of what the difference is.

It would be great to have at least on sentence explaining the purpose of the functions.

ZMQ error when starting second omc session

Description

When I create an OMCSession, close it with quit and open a new one ZMQ throws an error.

Strangely this works perfectly fine on all of my machines but one.
This also works fine in the virtual machines of the GitHub actions CI of a package I'm developing.

How to reproduce

julia> using OMJulia
julia> omc= OMJulia.OMCSession()
[ Info: Path to zmq file="/tmp/openmodelica.USERNAME.port.julia.LxagFYK6UA"
OMJulia.OMCSession(false, false, Dict{Any, Any}(), Dict{Any, Any}(), Dict{Any, Any}(), "", "/path/to/my/workingDir.jl, "", "", "", #undef, "", "", Any[], Dict{Any, Any}(), Dict{Any, Any}(), Dict{Any, Any}(), Dict{Any, Any}(), Dict("startTime" => "0.0", "stopTime" => "1.0", "numberOfIntervals" => "500", "stepSize" => "0.002", "tolerance" => "1e-6"), "", false, "", #undef, #undef, #undef, #undef, ZMQ.Context(Ptr{Nothing} @0x0000000001e83710, WeakRef[WeakRef(ZMQ.Socket(Ptr{Nothing} @0x0000000002423650, FileWatching._FDWatcher(Ptr{Nothing} @0x0000000001726890, 39, (1, 0), Base.GenericCondition{Base.Threads.SpinLock}(Base.InvasiveLinkedList{Task}(nothing, nothing), Base.Threads.SpinLock(0)), 0, (false, false))))]), ZMQ.Socket(Ptr{Nothing} @0x0000000002423650, FileWatching._FDWatcher(Ptr{Nothing} @0x0000000001726890, 39, (1, 0), Base.GenericCondition{Base.Threads.SpinLock}(Base.InvasiveLinkedList{Task}(nothing, nothing), Base.Threads.SpinLock(0)), 0, (false, false))), Process(`omc --interactive=zmq +z=julia.LxagFYK6UA`, ProcessRunning))
julia> OMJulia.sendExpression(omc, "quit()",parsed=false)
"quit requested, shutting server down\n"
julia> omc= OMJulia.OMCSession()
[ Info: Path to zmq file="/tmp/openmodelica.USERNAME.port.julia.xnIupNqu5H"
ERROR: ZMQ.StateError("Invalid argument")
Stacktrace:
 [1] connect
   @ ~/.julia/packages/ZMQ/R3wSD/src/socket.jl:65 [inlined]
 [2] OMJulia.OMCSession(omc::Nothing)
   @ OMJulia ~/.julia/packages/OMJulia/pPJUC/src/OMJulia.jl:176
 [3] OMJulia.OMCSession()
   @ OMJulia ~/.julia/packages/OMJulia/pPJUC/src/OMJulia.jl:88
 [4] top-level scope
   @ REPL[6]:1

Versions 'n stuff

OMJulia.jl: v0.2.0 https://github.com/OpenModelica/OMJulia.jl#master (should be d705d58)
ZMQ.jl: v1.2.1
OS: Ubuntu 20.04.4 LTS
OpenModelica: v1.20.0-dev-211-g882357bebd
Julia Version 1.7.2 (Commit bf53498635 (2022-02-06 15:21 UTC))
CPU: Intel(R) Xeon(R) Gold 6248R CPU @ 3.00GHz
LIBM: libopenlibm
LLVM: libLLVM-12.0.1 (ORCJIT, cascadelake)

OMJulia simulate command returns error

Hi everyone,
I've got an error message when execute simulate command. When I go to the directory that error point out, and run RLC exe, following message pop up:

RLC.exe - Entry point not found
Procedure entry point not found
_gfortran_os_error_at in the dynamic link library
C: \ Users \ USER \ AppData \ Local \ Temp \ jl_y6LgBj \ RLC.exe.

I am using win-10, OpenModelica1.17.0-64bit, Julia-1.6.1 and OMJulia v0.1.0 https://github.com/OpenModelica/OMJulia.jl#master

Attached openmodelica file and julia script.
RLC_OM.txt
RLC_OMJulia.txt

Below is the error the message I've got when I try to simulate my RLC model:

failed process: Process(`C:/Users/USUARIO/AppData/Local/Temp/jl_m25Fbu/RLC.exe`, ProcessExited(3221225785)) [3221225785]
Stacktrace:
  [1] pipeline_error
    @ .\process.jl:525 [inlined]
  [2] run(::Cmd; wait::Bool)
    @ Base .\process.jl:440
  [3] run
    @ .\process.jl:438 [inlined]
  [4] (::OMJulia.var"#29#31"{Bool, Vector{String}})()
    @ OMJulia C:\Users\USUARIO\.julia\packages\OMJulia\P5JuJ\src\OMJulia.jl:619
  [5] withenv(f::OMJulia.var"#29#31"{Bool, Vector{String}}, keyvals::Pair{String, String})
    @ Base .\env.jl:161
  [6] simulate(omc::OMJulia.OMCSession, resultfile::Nothing, simflags::Nothing; verbose::Bool)
    @ OMJulia C:\Users\USUARIO\.julia\packages\OMJulia\P5JuJ\src\OMJulia.jl:617
  [7] simulate (repeats 2 times)
    @ C:\Users\USUARIO\.julia\packages\OMJulia\P5JuJ\src\OMJulia.jl:569 [inlined]
  [8] top-level scope
    @ In[8]:1
  [9] eval
    @ .\boot.jl:360 [inlined]
 [10] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base .\loading.jl:1094

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Pipeline log files permission issues

Issue Description

OMJulia starts an omc process that writes to stdout.log and stderr.log. When an additional process starts or the previous OMJulia session wasn't closed correctly I have to restart Julia to close and remove these files.

                withenv("OPENMODELICAHOME" => omhome) do
                    this.omcprocess = open(pipeline(`$ompath $args2 $args3$args4`, stdout="stdout.log", stderr="stderr.log"))
                end

Suggested Changes

Write to unique IO streams in memory for each OMJulia session.
IOBuffer is breaking on Windows and isn't save to use, see JuliaLang/julia#39311.
Using undocumented Base.BufferStream() seems to work, though:

  out = Base.BufferStream()
  err = Base.BufferStream()
  try
      withenv("OPENMODELICAHOME" => omhome) do
          this.omcprocess = open(pipeline(`$ompath $args2 $args3$args4`, stdout=out, stderr=err))
      end
    # stdout = read(out, String)
  catch e
    println(read(err, String))
    rethrow(e)
  finally
    close(out)
    close(err)
  end

Versions 'n stuff

  • OpenModelica: v1.22.0-dev-285-gf718aa4020-cmake
  • OS: Windows 11
  • Julia v1.9.2

Parser failing for array of `TypeName`

OMJulia.API.getClassNames(omc;class_="Modelica") works fine.

OMJulia.API.getClassNames(omc;class_="Modelica", recursive=true)
gives:
ERROR: OMJulia.Parser.LexerError("Error while lexing")

Return dataframe from getSolutions

The getSolutions function behaves very different when setting input name=nothing. It's not returning solutions but a list of all variables in the result file.
I would expect to get the solution of all variables in that case.

The output format for getSolutions(mod, ["time","a"]) is Vector{Vector{Float64}}. Why not a data frame?
And I would expect to always get time in the data frame. Otherwise the solution of only a is useless.

Julia 1.0 compatibility?

I tried OMJulia in Windows using Julia 1.0.0 and got following error:

julia> using OMJulia
[ Info: Precompiling OMJulia [b9c49fa3-9548-50ca-88f4-bcd0bd4a191f]
ERROR: LoadError: syntax: extra token "OMCSession" after end of expression
Stacktrace:
 [1] include at .\boot.jl:317 [inlined]
 [2] include_relative(::Module, ::String) at .\loading.jl:1038
 [3] include(::Module, ::String) at .\sysimg.jl:29
 [4] top-level scope at none:2
 [5] eval at .\boot.jl:319 [inlined]
 [6] eval(::Expr) at .\client.jl:389
 [7] top-level scope at .\none:3
in expression starting at D:\apps\.julia\dev\OMJulia\src\OMJulia.jl:36
ERROR: Failed to precompile OMJulia [b9c49fa3-9548-50ca-88f4-bcd0bd4a191f] to D:\apps\.julia\compiled\v1.0\OMJulia\TnZao.ji.
Stacktrace:
 [1] macro expansion at .\logging.jl:313 [inlined]
 [2] compilecache(::Base.PkgId, ::String) at .\loading.jl:1184
 [3] macro expansion at .\logging.jl:311 [inlined]
 [4] _require(::Base.PkgId) at .\loading.jl:941
 [5] require(::Base.PkgId) at .\loading.jl:852
 [6] macro expansion at .\logging.jl:311 [inlined]
 [7] require(::Module, ::Symbol) at .\loading.jl:834

I wonder whether OMJulia is supposed to work with Julia 1.0?

Example from User's Guide not working

When running

using OMJulia
mod = OMJulia.OMCSession()
ModelicaSystem(mod, "D://workspace/OpenModelica/build/lib/omlibrary/Modelica 4.0.0/package.mo", "Modelica.Electrical.Analog.Examples.CauerLowPassAnalog")
simulate(mod, simflags="-override=outputFormat=csv")

similar to https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/omjulia.html#advanced-simulation I get an error for simulate:

ERROR: LoadError: MethodError: no method matching simulate(::OMJulia.OMCSession, ::Nothing, ::Nothing; simflags="-override=outputFormat=csv")
Closest candidates are:
  simulate(::Any, ::Any, ::Any; verbose) at C:\Users\Andreas\.julia\packages\OMJulia\USa2u\src\OMJulia.jl:591 got unsupported keyword argument "simflags"
  simulate(::Any, ::Any) at C:\Users\Andreas\.julia\packages\OMJulia\USa2u\src\OMJulia.jl:591 got unsupported keyword argument "simflags"
  simulate(::Any) at C:\Users\Andreas\.julia\packages\OMJulia\USa2u\src\OMJulia.jl:591 got unsupported keyword argument "simflags"

Problem is that resultfile and simflags are positional, not keyword arguments.

Fix documentation

Apparently something broke when generating the documentation:

julia> using OMJulia
julia> using OMJulia.API: API
julia> using CSV, DataFrames, PlotlyJS
julia> omc = OMJulia.OMCSession();
ERROR: IOError: could not spawn `omc --interactive=zmq -z=julia.4GhBQGED9v`: no such file or directory (ENOENT)

(https://docs.juliahub.com/General/OMJulia/stable/quickstart/#omjulia-api)

We need to re-generate the documentation and make sure this doesn't happen again.

Sometimes ZMQ freezes on sendExpression("quit()")

Sometimes (maybe 1 in 10 or 1 in 20 cases), ZMQ freezes after sendExpression(omc, "quit()").

The OMC instance shuts down properly, but the call never returns. I suppose that this could be a threading issue on the side of OMC so that quit() sometimes shuts down the process before the answer to the ZMQ message is sent.

The clean solution would probably be to look into the ZMQ handling in the OMC, but a quick fix could also be to simply skip the call to ZMQ.recv for the quit() message like this:

...
if expr == "quit()"
    return ""
end
message=ZMQ.recv(omc.socket)
...

If it seems that this clutters up the implementation of sendExpression too much, it would also be possible to implement quit(omc) as a separate function.

Add OSI-approved license to OMJulia top level folder

Currently JuliaRegistries/General#58444 fails, because of the missing license file, so we can't update our OMJulia version in the Julia general regestry.

OMJulia source files are using the OSMC-PL license, see e.g. https://github.com/OpenModelica/OMJulia.jl/blob/master/src/OMJulia.jl#L1-L27.

Our OSMC-PL license is problematic for adding OMJulia to the general registry since it is not part of the OSI-approved license.

Is there any reason to not just use a license that is OSI-aproved and allowes other to change OMJulia.jl? E.g. MIT license.
This package is only a API for OpenModelica and OpenModelica is not shipped with it.
So all generated code by omc is still under OSMC-PL license.

Or we use GPL-3.0, but then nobody is allowed to change OMJulia.

Register package at https://github.com/JuliaRegistries/Registrator.jl

I am working on a package which is not fully documented yet and hosted at https://gitlab.com/christiankral/OMRemote.jl. My package depends on OMJulia.jl. When I try to refer to OMJulia.jl in my Project.toml the registrar at https://github.com/JuliaRegistries/Registrator.jl complains, that OMJulia.jl is not registered.

So is there a reason why the package is not registered at https://github.com/JuliaRegistries/Registrator.jl? This would definitely also simply also the installation of OMJulia as Pkg.clone does not have to be used.

OMJulia not responding with long debug message

When I run the following script

loadModel(Modelica, {"4.0.0"});
getErrorString();

setCommandLineOptions("-d=newinst,backenddaeinfo,dumpSimCode");
getErrorString();

simulate(Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.FullRobot);
getErrorString();

with omc the total time is around 8 seconds.

When I convert the script to be used in OMJulia it will not finish (at least in an amount I'm willing to wait).

using OMJulia
omc = OMJulia.OMCSession("path/to/omc");
OMJulia.sendExpression(omc, "setCommandLineOptions(\"-d=newInst,dumpSimCode\")")
OMJulia.sendExpression(omc, "loadModel(Modelica)")
msg = OMJulia.sendExpression(omc, "simulate(Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.FullRobot)");

When I cancle the last command I get

julia> msg = OMJulia.sendExpression(omc, "simulate(Modelica.Mechanics.MultiBody.Examples.Systems.RobotR3.FullRobot)");
^CERROR: InterruptException:
Stacktrace:
 [1] poptask(W::Base.InvasiveLinkedListSynchronized{Task})
   @ Base ./task.jl:827
 [2] wait()
   @ Base ./task.jl:836
 [3] wait(c::Base.GenericCondition{Base.Threads.SpinLock})
   @ Base ./condition.jl:123
 [4] wait(fdw::FileWatching._FDWatcher; readable::Bool, writable::Bool)
   @ FileWatching /opt/julia/julia-1.7.1/share/julia/stdlib/v1.7/FileWatching/src/FileWatching.jl:533
 [5] wait
   @ ~/.julia/packages/ZMQ/R3wSD/src/socket.jl:52 [inlined]
 [6] _recv!(socket::ZMQ.Socket, zmsg::ZMQ.Message)
   @ ZMQ ~/.julia/packages/ZMQ/R3wSD/src/comm.jl:75
 [7] recv
   @ ~/.julia/packages/ZMQ/R3wSD/src/comm.jl:94 [inlined]
 [8] sendExpression(omc::OMJulia.OMCSession, expr::String)
   @ OMJulia ~/.julia/packages/OMJulia/ZLXEs/src/OMJulia.jl:1014
 [9] top-level scope
   @ REPL[7]:1

When I remove dumpSimCode OMJulia simulates fine in around 7 seconds.

My guess is that the debug log is to large to be handled.

How to specify version of additional Modelica libraries in ModelicaSystem

The documentation of ModelicaSystem shows the following text and example:

image

The third argument is apparently a list of additional libraries to be loaded. In the included example the library Modelica and others are loaded.

I have a user example that relies on the MSL 3.2.3:

model Test
  parameter Modelica.SIunits.Current I = 1 "Current";
equation

annotation(uses(Modelica(version="3.2.3")),
    experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002));
end Test;

Consider the following cases after applying

using OMJulia
mod = OMJulia.OMCSession()

Case 1: Do not specify Modelica

mod.ModelicaSystem("Test.mo", "Test")
mod.simulate()
  • Everything is good, even though Modelica is not explicitly specified
  • Does mod.ModelicaSystem read the uses annotation, or why does it work?

Case 2: Specify Modelica

mod.ModelicaSystem("Test.mo", "Test", ["Modelica"])
  • A warning is caused, indicating that the wrong Modelica version is loaded
Warning: Test requested package Modelica of version 3.2.3. Modelica 4.0.0 
is used instead which states that it is only compatible with a conversion script...

Case 3: How to specify the Modelica 3.2.3 library explicitly?

  • How can I specify the version number of Modelica (or any other library) explicitly through mod.ModelicaSystem("Test.mo", "Test", ...)?
  • When I try to load the Modelica 3.2.3 library through sendExpression it seems the be loaded correctly, as no error message is drawn
  • Therefore, if I try to load the Modelica 4.0.0 library through sendExpression I would expect a warning message, as the Modelica 4.0.0 library is not compatible with model Test; the following, however, works with not error message:
OMJulia.sendExpression(mod,"load(Modelica,{\"4.0.0\"})")
mod.ModelicaSystem("Test.mo", "Test")
mod.simulate()
  • As this example draws no warning, this brings me to the conclusion, that the Modelica 4.0.0 library is not loaded / used

Summary

The main question is: How can I specify the version number of any library through mod.ModelicaSystem("Test.mo", "Test", ...)?

Test core features of omc with OMJulia

Description

Add a periodic test to run core features of OpenModelica from OMJulia on:

  • Windows (windows-latest)
  • Ubuntu (ubuntu-latest, ubuntu-20)

with OpenModelica compiler versions

  • nightly
  • stable
  • release
  • the last N stable versions (difficult to update automatically)

to test

  • Model build / simulation /results
  • FMU export
  • ...

Related issues

OpenModelica/OpenModelica#11414

ZMQ freezes on first command after session is created

Sometimes (quite rarely), the first call to sendExpression() after an OMCSession is created freezes.

Stacktrace of InterruptException (after CTRL-C):

 [1] wait(::FileWatching._FDWatcher; readable::Bool, writable::Bool) at /build/julia/src/julia-1.5.0/usr/share/julia/stdlib/v1.5/FileWatching/src/FileWatching.jl:529
 [2] wait at /home/cslz90/.julia/packages/ZMQ/R3wSD/src/socket.jl:52 [inlined]
 [3] _recv!(::ZMQ.Socket, ::ZMQ.Message) at /home/cslz90/.julia/packages/ZMQ/R3wSD/src/comm.jl:75
 [4] recv at /home/cslz90/.julia/packages/ZMQ/R3wSD/src/comm.jl:94 [inlined]
 [5] sendExpression(::OMJulia.OMCSession, ::String) at /home/cslz90/.julia/packages/OMJulia/ZLXEs/src/OMJulia.jl:1014
 [6] setupOMCSession(::String, ::String; quiet::Bool, checkunits::Bool) at /home/cslz90/.julia/packages/ModelicaScriptingTools/G5LLK/src/ModelicaScriptingTools.jl:374

setupOMCSession is my own code which contains the following relevant lines with the second line being the one that shows up in the stacktrace:

omc = OMCSession()
sendExpression(omc, "cd(\"$(moescape(outdir))\")")

This happens with the release version 0.1.0 of OMJulia. I believe I have also encountered it with the current version from the master branch in the past, but I cannot confirm that since I have switched back to the official released version some time ago.

I will try to introduce a sleep for 100ms between the creation of the Session and the first sendExpression() and report back whether this workaround is successful.

cannot linearise() in Open Modelica v1.16 environment

In my Open Modelica v1.16.2(64bit win10) environment, OMJulia'slinearise()function does not work properly. On the other hand, in the Open Modelica v1.13 environment, it worked correctly.

This is probably because the file name of the linearized model is generated as "linear_**model name**.mo" in Open Modelica v1.13, while the name is generated as "linearized_model.mo" in Open Modelica v1.16.2.

ZMQ freezes when receiving data

Send and recv is currently handled by

function sendExpression(omc, expr)
   ZMQ.send(omc.socket, expr)
   message=ZMQ.recv(omc.socket)
   return Parser.parseOM(unsafe_string(message))
end

The issue here is that I have managed to freeze it a couple of times (The reason being is that we have ZMQ communication but we do not have any timeout or polling to make the decision to throw a communication error and terminate).

This permanently blocks OMJulia and you need to quit the application. It is possible to use polling or timeout techniques to prevent this behavior. If someone else thinks that could be a good addition I could implement it :)

omc stays running when julia is exited

Is there an option to close/shutdown an active OMJulia.OMCSession()?

When I run multiple OMCSessions and exit Julia afterwards there are still multiple processes omc --interactive=zmq +z=julia.TrFYWsxcaT running. The same happens if I kill an active OMCSession while omc is running some task (+ I get the same error as in ticket #12).
Those are preventing me from rebuilding omc and I have to search and kill them manually.

OMJulia not working inside Docker container

Description

I have a Julia package that is building the documentation inside a Docker container using Documenter.jl.

My CI fails to build the documentation, because OMJulia doesn't work inside a docker container, because the ZMQ server port file can't be created.

julia> using OMJulia
julia> omc=OMJulia.OMCSession()
[ Info: Path to zmq file="/tmp/openmodelica..port.julia.s7DsM0rBD2"
Execution failed!
ERROR: Timeout: ZMQ server port file "/tmp/openmodelica..port.julia.s7DsM0rBD2" not created yet.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] OMJulia.OMCSession(omc::Nothing)
   @ OMJulia ~/.julia/packages/OMJulia/EXbLd/src/OMJulia.jl:170
 [3] OMJulia.OMCSession()
   @ OMJulia ~/.julia/packages/OMJulia/EXbLd/src/OMJulia.jl:88
 [4] top-level scope
   @ REPL[13]:1

How to reproducer

Create a dockerfile with:

FROM julia

# Get OpenModelica repo and key
RUN apt-get update && \
    apt-get install -qy \
      ca-certificates \
      curl \
      gnupg \
      lsb-release && \
    curl -fsSL http://build.openmodelica.org/apt/openmodelica.asc | gpg --dearmor -o /usr/share/keyrings/openmodelica-keyring.gpg && \
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/openmodelica-keyring.gpg] https://build.openmodelica.org/apt \
      $(lsb_release -cs) nightly" | tee /etc/apt/sources.list.d/openmodelica.list > /dev/null

# Install OpenModelica nightly
RUN apt update && \
    apt install -qy openmodelica

# Set USER
ENV USER=${USER_NAME}

Build the container

$ docker build --build-arg USER_NAME=$(whoami) -t julia-with-omc .

Start the container and execute Julia commands

$ docker run --rm -it julia-with-omc julia
(@v1.8) pkg> add https://github.com/OpenModelica/OMJulia.jl#master
julia> using OMJulia
julia> omc=OMJulia.OMCSession()

Method definition ModelicaSystem(OMJulia.OMCSession) overwritten

When precompiling OMJulia I get a warning about overwritten methods:

┌ OMJulia [0f4fe800-344e-11e9-2949-fb537ad918e1]
│  WARNING: Method definition ModelicaSystem(OMJulia.OMCSession) in module OMJulia at D:\path\to\OMJulia.jl\src\modelicaSystem.jl:71 overwritten at D:\path\to\OMJulia.jl\src\modelicaSystem.jl:138.
│    ** incremental compilation may be fatally broken for this module **
│
│  WARNING: Method definition kwcall(Any, typeof(OMJulia.ModelicaSystem), OMJulia.OMCSession) in module OMJulia at D:\path\to\OMJulia.jl\src\modelicaSystem.jl:71 overwritten at D:\path\to\OMJulia.jl\src\modelicaSystem.jl:138.
│    ** incremental compilation may be fatally broken for this module **
└

Does not work with Julia 1.4

The following works fine in Julia 1.1, but 1.4 refuses to start:

import OMJulia
om=OMJulia.OMCSession()
OMJulia.sendExpression(om, "1+1")

Release of next version of OMJulia?

I would really like to be able to install the current repository version of OMJulia with pkg> add OMJulia, especially because of the fix for #22. As I understand this only requires an update of the Project.toml and a merge request on https://github.com/JuliaRegistries/General .

Currently, I need to manually clone the repository and activate the local copy, because due to JuliaLang/julia#33111 even pkg> add https://github.com/OpenModelica/OMJulia.jl is not working. This is quite cumbersome to include in a CI script. 😩

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.