GithubHelp home page GithubHelp logo

fmu.nim's Introduction

fmu.nim

Purpose

The purpose of this library is enabling the creation of FMU files that can be later used in many compatible simulation packages such as OpenModelica, Matlab, Dymola, ...

This library is heavily based on fmusdk.

Installing

You need Nim v2.0. You can use choosenim in order to install Nim.

To intall the fmu.nim library, as usual, with nimble:

nimble install https://github.com/SciNim/fmu.nim

Status

Right now, you can create both Model Exchange and Co-Simulation models using FMI2.0.

The five examples from fmusdk are working.

Besides, it can create easily multiplatform FMU's (they can work both in windows and linux).

How it works?

It creates:

  1. the libraries: .so and/or .dll
  2. the folder structure as per the specification
  3. the XML with the model details

Then it packs everything in a zip file and changes the extension into .fmu.

How to use it?

Go to the examples folder.

The following command will generate inc.so (in Linux) and embed it into inc.fmu as a Model Exchange:

$ nim c -r -d:fmu2me inc

In order to create a co-simulation replace -d:fmu2me with -d:fmu2cs. The source code using one or the other looks like:

when defined(fmu2me):
  values.exportFmu("values.fmu")

when defined(fmu2cs):
  values.exportFmu("values.fmu", fmi2CoSimulation)

In order to test the models, one can use FMUComplianceChecker:

$ .../fmuCheck.linux64 -h 1 -s 11 -f -l 6 -e values.log values.fmu

where:

  • -h 1: steps every second
  • -s 11: during 11 seconds
  • -f: forces showing all the values (inputs, outputs, locals)
  • -l 6: logs every detail
  • -e values.log: stores the logging under values.log
  • values.fmu: selects the FMU to be used

or with fmusim (from fmusdk package):

$ ./fmusim_me inc.fmu 5 0.1

this will simulate during 5seconds using 0.1 second steps. it will create the file results.csv.

FMU compatible with windows and linux

If you compile like this:

nim c -r -d:fmu2me inc

you will get a FMU that is compatible only with the platform in which it was compile.

But if you compile using zig:

nim c -r -d:fmu2me -d:zig inc

you will get a FMU compatible with windows and linux (amd64 in both cases).

Getting zig

Install zig as you would do in windows or linux. (In windows, you need to have the binary reachable in the path; in Linux your package manager will take care of that).

Then you need to install with nimble (Nim package manager) the package: zigcc.

nimble install zigcc

(this is the same for both windows and linux; in windows you might need to install git)

Details

Intro

In general terms, we are making Nim to export C functions fulfilling the naming conventions of the FMU standard.

Importing an FMU in OpenModelica

In Linux, open:

$ OMEdit

Then import the created FMU:

Create a new Model (we will use the imported FMU in it):

Then drag-n-drop the FMU into the model:

Add an output for the integer. For that, drag-n-drop IntegerOutput on the model:

and connect the FMU instance to IntegerOutput:

Configure the simulation:

At this point, OpenModelica ask you to store the model somewhere (example.mo file). Select whereever it suits you.

Model

A new model requires the info such as:

  id      = "inc"
  guid    = "{8c4e810f-3df3-4a00-8276-176fa3c9f008}"

We will call the model template with these values. The model template is defined in src/fmu.nim. This calls model2 template (another template within src/fmu.nim). They both are responsible for structuring the code: the custom defined functions plus the other functions required by the standard.

All this will create two modes of operations for the code:

  1. When compiled as a library, it will create a library such as inc.so.
  2. When compiled as an app it uses src/lib/fmubuilder.nim:
  • Creates the folder structure
  • Creates the XML
  • Compress everything into a .fmu file.

Manual

setStartValues

Called by fmi2Instantiate with signature setStartValues(comp:Fmu).

In fmusdk, it initialize everything. This is no needed here. Right now this would only be needed in case of requiring to setup something during the FMU instantiation phase.

calculateValues

Calculate the values of the FMU (Functional Mock-up Unit) variables at a specific time step during simulation.

This function is defined by the user and called from getters.nim (fmi2GetReal, fmi2GetInteger, fmi2GetBoolean, fmi2GetString) and common.nim (fmi2ExitInitializationMode).

Lazy set values (given it is only called when isDirtyValues == true in the model) for all variable that are computed from other variables.

Example: inc.nim

Defines:

  proc calculateValues*(comp: FmuRef) = 
    if comp.state == modelInitializationMode:
        # set first time event
        comp.eventInfo.nextEventTimeDefined = fmi2True
        comp.eventInfo.nextEventTime        = 1 + comp.time

In this case, calculateValues creates new temporal events. In particular, creates in the InitializationMode state a new event 1s after the start.

eventUpdate

Used to set the next time event, if any.

Example: inc.nim

Reacts to events. In the inc.nim example, the first event was created in calculateValues.

In the inc.nim case, eventUpdate reacts to the event by creating a new event.

  • TODO: To talk about:
    type
      fmi2EventInfo* {.bycopy.} = object
        newDiscreteStatesNeeded*: fmi2Boolean
        terminateSimulation*: fmi2Boolean
        nominalsOfContinuousStatesChanged*: fmi2Boolean
        valuesOfContinuousStatesChanged*: fmi2Boolean
        nextEventTimeDefined*: fmi2Boolean
        nextEventTime*: fmi2Real
    and about: comp.isNewEventIteration

getReal

This is a user defined function with signature proc getReal*(comp: FmuRef; key: string):float. It is called by getters.nim in fmi2GetReal.

It is responsible for calculating the float values.

Example: values.nim

Defined as:

  proc getReal*(comp: FmuRef;
                key: string): float =
    case key
    of "myFloat": comp["myfloat"].valueR
    of "myFloatDerivative": -comp["myfloat"].valueR
    else: 0.0

TODO

  • unit testing for the examples
  • To simulate within Nim. This would prevent the need for fmuChecker.

Interesting projects related to FMU

fmu.nim's People

Contributors

mantielero avatar

Stargazers

Sang woo Ham avatar Ludger avatar Regis Caillaud avatar Markus Gonser avatar Willi Kappler avatar  avatar

Watchers

 avatar

fmu.nim's Issues

DISABLE_PREFIX

This is used in C compilation. For nim, we should tweak the exportc.

Compile with zig

It would be great being able to create multiplatform FMU's using zig for compilation.

Fully create `modelDescription.xml`

The file modelDescription.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<fmiModelDescription guid="{8c4e810f-3df3-4a00-8276-176fa3c9f008}" 
                     numberOfEventIndicators="0" 
                     modelName="inc" 
                     fmiVersion="2.0">
  <ModelExchange modelIdentifier="inc">
    <SourceFiles>
      <File name="inc.c" />
    </SourceFiles>
  </ModelExchange>
  <LogCategories>
    <Category name="logAll" />
    <Category name="logError" />
    <Category name="logFmiCall" />
    <Category name="logEvent" />
  </LogCategories>
  <ModelVariables>
    <ScalarVariable variability="discrete" 
                    valueReference="0" 
                    description="counts the seconds" 
                    causality="output" 
                    initial="exact" 
                    name="counter">
      <Integer start="1" />
    </ScalarVariable>
  </ModelVariables>
  <ModelStructure>
    <Outputs>
      <Unknown index="1" />
    </Outputs>
  </ModelStructure>
</fmiModelDescription>

componentEnvironment not being propagated

When the model is instantiated, componentEnvironment is passed by the simulation environment ħere as we can see in the this type declaration: fmi2CallbackFunctions.

The issue is clear when tested by fmuChecked.linux64:

[ERROR][FMUCHK] FMU logger callback does not propagate component environment to the application

The issue is that, for some reason, functions.componentEnvironment == nil in fmi2Instantiate.

Remove the includes

Convert the includes into imports, in order to make it behave more like a library.

Create folder structure

Create the folder structure using Nim rather than resusing the structure created by fmusdk

.fmu file not working with OpenModelica

Using OMEdityou can import the model. Later you can instantiate it in a new model. The simulation raises:

Fallo en el proceso
[INFO][inc] [logFmiCall][FMU status:OK] fmi2Instantiate: GUID={8c4e810f-3df3-4a00-8276-176fa3c9f008} SIGSEGV: Illegal storage access. (Attempt to read from nil?) 
Fallo en el proceso Simulation process failed. Exited with code 11.

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.