OpenModelica

https://openmodelica.org/download/download-linux/

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo curl -fsSL http://build.openmodelica.org/apt/openmodelica.asc | sudo 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 \
  $(cat /etc/os-release | grep "\(UBUNTU\\|DEBIAN\\|VERSION\)_CODENAME" | sort | cut -d= -f 2 | head -1) \
  stable" | sudo tee /etc/apt/sources.list.d/openmodelica.list
sudo apt update
sudo apt install openmodelica

https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/ompython.html

git clone https://github.com/OpenModelica/OpenModelica
python
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
omc.sendExpression("getVersion()")
## 'OpenModelica 1.23.1'
omc.sendExpression("installPackage(Modelica)")
omc.sendExpression("loadModel(Modelica)")
omc.sendExpression("loadFile(\"./OpenModelica/OMCompiler/Examples/BouncingBall.mo\")")
## True
omc.sendExpression("getClassNames()")
## ('BouncingBall', 'ModelicaServices', 'Complex', 'Modelica')
omc.sendExpression("instantiateModel(BouncingBall)")
## class BouncingBall
##   parameter Real e = 0.7 "coefficient of restitution";
##   parameter Real g = 9.81 "gravity acceleration";
##   Real h(start = 1.0, fixed = true) "height of ball";
##   Real v(fixed = true) "velocity of ball";
##   Boolean flying(start = true, fixed = true) "true, if ball is flying";
##   Boolean impact;
##   Real v_new(fixed = true);
##   Integer foo;
## equation
##   impact = h <= 0.0;
##   foo = if impact then 1 else 2;
##   der(v) = if flying then -g else 0.0;
##   der(h) = v;
##   when {h <= 0.0 and v <= 0.0, impact} then
##     v_new = if edge(impact) then -e * pre(v) else 0.0;
##     flying = v_new > 0.0;
##     reinit(v, v_new);
##   end when;
## end BouncingBall;
omc.sendExpression("simulate(BouncingBall, stopTime=3.0, outputFormat=\"csv\")")
## {
##   'resultFile': 'BouncingBall_res.csv',
##   'simulationOptions': "startTime = 0.0, stopTime = 3.0, numberOfIntervals = 500, tolerance = 1e-6, method = 'dassl',
##                         fileNamePrefix = 'BouncingBall', options = '', outputFormat = 'csv', variableFilter = '.*', cflags = '', simflags = ''",
##   'messages': 'LOG_SUCCESS       | info    | The initialization finished successfully without homotopy method.\n
##                LOG_SUCCESS       | info    | The simulation finished successfully.\n',
##   'timeFrontend': 0.067590884,
##   'timeBackend': 0.023814135,
##   'timeSimCode': 0.004248845,
##   'timeTemplates': 0.007150218000000001,
##   'timeCompile': 1.506673157,
##   'timeSimulation': 0.035231169,
##   'timeTotal': 1.6510822539999999
## }
df = pd.read_csv("BouncingBall_res.csv")
df
##       time             h        v   der(h)  der(v)  v_new  foo  flying  impact
## 0    0.000  1.000000e+00  0.00000  0.00000   -9.81    0.0    2       1       0
## 1    0.006  9.998234e-01 -0.05886 -0.05886   -9.81    0.0    2       1       0
## 2    0.012  9.992937e-01 -0.11772 -0.11772   -9.81    0.0    2       1       0
## 3    0.018  9.984108e-01 -0.17658 -0.17658   -9.81    0.0    2       1       0
## 4    0.024  9.971747e-01 -0.23544 -0.23544   -9.81    0.0    2       1       0
## ..     ...           ...      ...      ...     ...    ...  ...     ...     ...
## 687  2.982  2.101988e-11  0.00000  0.00000    0.00    0.0    1       0       1
## 688  2.988  2.101988e-11  0.00000  0.00000    0.00    0.0    1       0       1
## 689  2.994  2.101988e-11  0.00000  0.00000    0.00    0.0    1       0       1
## 690  3.000  2.101988e-11  0.00000  0.00000    0.00    0.0    1       0       1
## 691  3.000  2.101988e-11  0.00000  0.00000    0.00    0.0    1       0       1
## 
## [692 rows x 9 columns]
df.plot(x="time", y="h")
plt.savefig("BouncingBall_res.png", bbox_inches='tight')

Information - How to Debug

## Getting error messages of the previous command
omc.sendExpression("getErrorString()")
## '[<interactive>:1:1-1:0:writable] Error: Class getDummyError not found in scope <global scope> (looking for a function or record).\n'

https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/interop_c_python.html

## TCP Server in Python
vi getValue.py
================================
import socket

HOST = '127.0.0.1'
PORT = 12345

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s :
    s.bind((HOST, PORT))
    s.listen()
    print(f"Listening on {HOST}:{PORT}")
    while True :
        conn, addr = s.accept()
        with conn :
            print('Connected by', addr)
            while True :
                data = conn.recv(1024)
                if not data :
                    break
                print('Received', data.decode('utf-8'))
            print('Connection closed by', addr)
================================
python getValue.py
## TCP Client in C
vi sendValue.c
================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include "sendValue.h"

int sendValue(const char *server_ip, int server_port, float value) {
    int sockfd;
    struct sockaddr_in server_addr;
    char message[64];
    snprintf(message, sizeof(message), "%f", value);
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation failed");
        return -1;
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(server_port);
    if (inet_pton(AF_INET, server_ip, &server_addr.sin_addr) <= 0) {
        perror("Invalid address");
        close(sockfd);
        return -1;
    }
    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Connection failed");
        close(sockfd);
        return -1;
    }
    if (send(sockfd, message, strlen(message), 0) < 0) {
        perror("Send failed");
        close(sockfd);
        return -1;
    }
    printf("Message sent: %s\n", message);
    close(sockfd);
    return 0;
}
================================
vi sendValue.h
================================
#ifndef SENDVALUE_H
#define SENDVALUE_H

int sendValue(const char *server_ip, int server_port, float value);

#endif
================================
gcc -c -o sendValue.o sendValue.c
## Calling external C function sendValue() every 1 second
vi BouncingBall.mo
================================
model BouncingBall
  parameter Real e=0.7 "coefficient of restitution";
  parameter Real g=9.81 "gravity acceleration";
  Real h(fixed=true, start=1) "height of ball";
  Real v(fixed=true) "velocity of ball";
  Boolean flying(fixed=true, start=true) "true, if ball is flying";
  Boolean impact;
  Real v_new(fixed=true);
  Integer foo;
  Clock c = Clock(1);
  
  function sendValue
    input String server_ip = "127.0.0.1";
    input Integer server_port = 12345;
    input Real value = 0.0;
    external "C" sendValue(server_ip, server_port, value) annotation(Include="#include \"sendValue.h\"", Library="sendValue.o");
  end sendValue;

equation
  impact = h <= 0.0;
  foo = if impact then 1 else 2;
  der(v) = if flying then -g else 0;
  der(h) = v;

  when {h <= 0.0 and v <= 0.0,impact} then
    v_new = if edge(impact) then -e*pre(v) else 0;
    flying = v_new > 0;
    reinit(v, v_new);
  end when;
  
  when {sample(0, 1)} then
    sendValue("127.0.0.1", 12345, h);
  end when;

end BouncingBall;
================================
python
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
omc.sendExpression("loadFile(\"./BouncingBall.mo\")")
omc.sendExpression("simulate(BouncingBall, stopTime=3.0, outputFormat=\"csv\")")
## {
##   'resultFile': 'BouncingBall_res.csv',
##   'simulationOptions': "startTime = 0.0, stopTime = 3.0, numberOfIntervals = 500, tolerance = 1e-6, method = 'dassl',
##                         fileNamePrefix = 'BouncingBall', options = '', outputFormat = 'csv', variableFilter = '.*', cflags = '', simflags = ''",
##   'messages': 'LOG_SUCCESS       | info    | The initialization finished successfully without homotopy method.\n
##                Message sent: 1.000000\n
##                Message sent: 0.225060\n
##                Message sent: 0.042434\n
##                Message sent: 0.000000\n
##                LOG_SUCCESS       | info    | The simulation finished successfully.\n',
##   'timeFrontend': 0.002844552,
##   'timeBackend': 0.005307907000000001,
##   'timeSimCode': 0.0059751560000000006,
##   'timeTemplates': 0.008850144,
##   'timeCompile': 1.118291402,
##   'timeSimulation': 0.018550764,
##   'timeTotal': 1.159920236
## }
## ===== Data received by getValue.py =====
## Listening on 127.0.0.1:12345
## Connected by ('127.0.0.1', 52362)
## Received 1.000000
## Connection closed by ('127.0.0.1', 52362)
## Connected by ('127.0.0.1', 52376)
## Received 0.225060
## Connection closed by ('127.0.0.1', 52376)
## Connected by ('127.0.0.1', 52386)
## Received 0.042434
## Connection closed by ('127.0.0.1', 52386)
## Connected by ('127.0.0.1', 52402)
## Received 0.000000
## Connection closed by ('127.0.0.1', 52402)

Daiphys is a professional-service company for research and development of leading-edge technologies in science and engineering.
Get started accelerating your business through our deep expertise in R&D with AI, quantum computing, and space development; please get in touch with Daiphys today!

Name*


Email*


Message*




* Indicates required field

Daiphys Technologies LLC - https://www.daiphys.com/

  • Last modified: 2024/07/23 17:00
  • by Daiphys