org.javafmi.framework.FmiSimulation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fmu-framework Show documentation
Show all versions of fmu-framework Show documentation
javaFMI is a Java Library for the functional mock-up interface (or FMI). FMI defines a standardized interface to be used in computer simulations. The FMI Standard has beed developed by a large number of software companies and research centers that have worked in a cooperation project under the name of MODELISAR. This library addresses the connection of a java application with a FMU (functional mock-up unit).
/*
* Copyright 2013-2016 SIANI - ULPGC
*
* This File is part of JavaFMI Project
*
* JavaFMI Project is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* JavaFMI Project is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JavaFMI. If not, see .
*/
package org.javafmi.framework;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import static java.util.stream.IntStream.range;
@SuppressWarnings({"UnusedParameters", "unchecked"})
public abstract class FmiSimulation extends FmiContainer {
private ModelDescription modelDescription;
private double currentTime = 0;
private Logger logger;
private Map variables = new HashMap<>();
private Map states = new HashMap<>();
private Map pendingSets = new HashMap<>();
public FmiSimulation() {
modelDescription = define().terminate();
}
public abstract Model define();
public abstract Status init();
public abstract Status doStep(double stepSize);
public abstract Status reset();
public abstract Status terminate();
public ModelDescription modelDescription() {
return modelDescription;
}
public Logger logger() {
return logger != null ? logger : new Logger(getClass().getName(), System.out);
}
public void logger(Logger logger) {
this.logger = logger;
}
public Status enterInitializationMode() {
init();
return Status.OK;
}
public Status exitInitializationMode() {
pendingSets.clear();
return Status.OK;
}
public Status setupExperiment(boolean toleranceDefined, double tolerance, double startTime, boolean stopTimeDefined, double stopTime) {
return Status.OK;
}
public Status doStep(double currentCommunicationPoint, double communicationStepSize, boolean newStep) {
currentTime += communicationStepSize;
return doStep(communicationStepSize);
}
public Status cancelStep() {
return Status.WARNING;
}
public double[] getDirectionalDerivative(String[] nameUnknowns, String[] nameKnowns, double[] dvKnown) {
return new double[]{-1.0};
}
public double[] getRealOutputDerivatives(String[] nameVariable, int[] order) {
return new double[]{-1.0};
}
public Status setRealInputDerivatives(String[] nameVariable, int[] order, double[] values) {
return Status.OK;
}
public int[] getInteger(int... valueReferences) {
int intValues[] = new int[valueReferences.length];
for (int i = 0; i < valueReferences.length; i++) {
intValues[i] = (int) variable(valueReferences[i]).getValue();
}
return intValues;
}
public double[] getReal(int... valueReferences) {
double doubleValues[] = new double[valueReferences.length];
for (int i = 0; i < valueReferences.length; i++) {
doubleValues[i] = (double) variable(valueReferences[i]).getValue();
}
return doubleValues;
}
public boolean[] getBoolean(int... valueReferences) {
boolean boolValues[] = new boolean[valueReferences.length];
for (int i = 0; i < valueReferences.length; i++) {
boolValues[i] = (boolean) variable(valueReferences[i]).getValue();
}
return boolValues;
}
public String[] getString(int... valueReferences) {
String stringValues[] = new String[valueReferences.length];
for (int i = 0; i < valueReferences.length; i++) {
stringValues[i] = (String) variable(valueReferences[i]).getValue();
}
return stringValues;
}
protected Status setVariable(int valueReference, Object value) {
if (!variables.containsKey(valueReference)) {
pendingSets.put(valueReference, value);
return Status.OK;
}
return variable(valueReference).setValue(value);
}
private Variable variable(int valueReference) {
return variables.get(valueReference);
}
public Status setReal(int valueReferences[], double values[]) {
return range(0, valueReferences.length).boxed()
.map(i -> setVariable(valueReferences[i], values[i]))
.filter(s -> s != Status.OK)
.findFirst().orElse(Status.OK);
}
public Status setInteger(int valueReferences[], int values[]) {
return range(0, valueReferences.length).boxed()
.map(i -> setVariable(valueReferences[i], values[i]))
.filter(s -> s != Status.OK)
.findFirst().orElse(Status.OK);
}
public Status setBoolean(int valueReferences[], boolean values[]) {
return range(0, valueReferences.length).boxed()
.map(i -> setVariable(valueReferences[i], values[i]))
.filter(s -> s != Status.OK)
.findFirst().orElse(Status.OK);
}
public Status setString(int valueReferences[], String values[]) {
return range(0, valueReferences.length).boxed()
.map(i -> setVariable(valueReferences[i], values[i]))
.filter(s -> s != Status.OK)
.findFirst().orElse(Status.OK);
}
protected void registerReal(String name, Variable.Getter getter) {
register(name, getter);
}
protected void registerReal(String name, Variable.Getter getter, Variable.Setter setter) {
register(name, getter, setter);
}
protected void registerInteger(String name, Variable.Getter getter) {
register(name, getter);
}
protected void registerInteger(String name, Variable.Getter getter, Variable.Setter setter) {
register(name, getter, setter);
}
protected void registerBoolean(String name, Variable.Getter getter) {
register(name, getter);
}
protected void registerBoolean(String name, Variable.Getter getter, Variable.Setter setter) {
register(name, getter, setter);
}
protected void registerString(String name, Variable.Getter getter) {
register(name, getter);
}
protected void registerString(String name, Variable.Getter getter, Variable.Setter setter) {
register(name, getter, setter);
}
protected void register(String name, Variable variable) {
int valueReference = valueReferenceOf(name);
variables.put(valueReference, variable);
if (pendingSets.containsKey(valueReference)) setVariable(valueReference, pendingSets.remove(valueReference));
}
private int valueReferenceOf(String name) {
return modelDescription.variables().stream().filter(i -> i.name().equals(name)).findFirst().get().valueReference();
}
private void register(String name, Variable.Getter getter) {
register(name, new Variable() {
@Override
public Object getValue() {
return getter.get();
}
@Override
public Status setValue(Object value) {
return Status.ERROR;
}
});
}
private void register(String name, Variable.Getter getter, Variable.Setter setter) {
register(name, new Variable() {
@Override
public Object getValue() {
return getter.get();
}
@Override
public Status setValue(Object value) {
setter.set(value);
return Status.OK;
}
});
}
protected void loadResource(String resourcePath) {
try {
InputStream stream = getClass().getClassLoader().getResource(resourcePath).openStream();
FileOutputStream outputStream = new FileOutputStream(new File(resourcePath));
int bytes;
byte[] buffer = new byte[2048];
while ((bytes = stream.read(buffer, 0, 2048)) > 0) {
outputStream.write(buffer, 0, bytes);
}
stream.close();
outputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Status getState(String stateId) {
states.put(stateId, getState());
return Status.OK;
}
protected State getState() {
State state = new State(currentTime);
variables.keySet().forEach(n -> state.put(nameOf(n), variable(n).getValue()));
return state;
}
protected void setState(State state) {
state.keySet().stream().forEach(n -> variable(valueReferenceOf(n)).setValue(state.get(n)));
currentTime = state.time();
}
public Status setState(String state) {
if (!states.containsKey(state)) return Status.ERROR;
setState(states.get(state));
return Status.OK;
}
public Status freeState(String state) {
if (!states.containsKey(state)) return Status.ERROR;
states.remove(state);
return Status.OK;
}
private String nameOf(Integer valueReference) {
return modelDescription.variables().get(valueReference - 1).name();
}
@SuppressWarnings("unused")
public enum Status {
OK(0), WARNING(1), DISCARD(2), ERROR(3), FATAL(4), PENDING(5);
private final int code;
Status(int code) {
this.code = code;
}
public int code() {
return code;
}
@Override
public String toString() {
return this.name().toLowerCase();
}
}
}