All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javafmi.framework.FmiSimulation Maven / Gradle / Ivy

Go to download

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).

There is a newer version: 2.26.5
Show newest version
/*
 *  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();
        }
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy