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

org.intocps.maestro.plugin.JacobianFixedStep Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
package org.intocps.maestro.plugin;

import org.intocps.maestro.ast.LexIdentifier;
import org.intocps.maestro.ast.node.PExp;
import org.intocps.maestro.ast.node.PStateDesignator;
import org.intocps.maestro.ast.node.PStm;
import org.intocps.maestro.ast.node.SBlockStm;
import org.intocps.maestro.core.messages.IErrorReporter;
import org.intocps.maestro.framework.fmi2.Fmi2SimulationEnvironment;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static org.intocps.maestro.ast.MableAstFactory.*;
import static org.intocps.maestro.ast.MableBuilder.*;
import static org.intocps.maestro.plugin.LogUtil.simLog;

public class JacobianFixedStep {
    final static String fixedStepStatus = "fix_status";
    private final static int FMI_OK = 0;
    private final static int FMI_WARNING = 1;
    private final static int FMI_DISCARD = 2;
    private final static int FMI_ERROR = 3;
    private final static int FMI_FATAL = 4;
    private final static int FMI_PENDING = 5;
    private final static int FMI_STATUS_LAST_SUCCESSFUL = 2;
    static int loopCounter = 0;


    /**
     * @param loopAccumulatingVars vars before while
     * @param list                 the list to iterate
     * @param size                 the list size
     * @param handler              (index, element) -> return what should happen
     * @return a block with the while
     */
    static SBlockStm loopComponents(Consumer> loopAccumulatingVars, PExp list, PExp size, BiFunction> handler) {
        String indexVarName = "fix_indexing_" + loopCounter++;
        List body = new Vector<>();

        body.add(newVariable(indexVarName, newAIntNumericPrimitiveType(), newAIntLiteralExp(0)));

        loopAccumulatingVars.accept(body);

        List whileBody = new Vector<>(handler.apply(newAIdentifierExp(indexVarName), arrayGet(list, newAIdentifierExp(indexVarName))));
        whileBody.add(newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(indexVarName)),
                newPlusExp(newAIdentifierExp(newAIdentifier(indexVarName)), newAIntLiteralExp(1))));

        body.add(newWhile(newALessBinaryExp(newAIdentifierExp(newAIdentifier(indexVarName)), size.clone()), newABlockStm(whileBody)));

        return newABlockStm(body);
    }

    public static List generate(Fmi2SimulationEnvironment env, IErrorReporter errorReporter, final List componentNames,
            String componentsIdentifier, PExp stepSize, PExp startTime, PExp endTime,
            Set relations) throws ExpandException, InstantiationException {
        Fmi2SimulationEnvironment unitRelationShip = (Fmi2SimulationEnvironment) env;
        Function getCompStatusDesignator =
                comp -> newAArayStateDesignator(newAIdentifierStateDesignator(newAIdentifier(fixedStepStatus)),
                        newAIntLiteralExp(componentNames.indexOf(comp)));

        LexIdentifier end = newAIdentifier("end");
        LexIdentifier time = newAIdentifier("time");
        String fix_stepSize = "fix_stepSize";
        String fix_recoveryStepSize = "fix_recoveryStepSize";
        String fix_recovering = "fix_recovering";
        LexIdentifier fixedStepOverallStatus = newAIdentifier("fix_global_status");
        LexIdentifier compIndexVar = newAIdentifier("fix_comp_index");


        Function getCompStatusExp = comp -> arrayGet(fixedStepStatus, componentNames.indexOf(comp));


        BiConsumer, Map.Entry>> checkStatus = (inLoopAndMessage, list) -> {
            List body = new Vector<>(Arrays.asList(newExpressionStm(
                    call("logger", "log", newAIntLiteralExp(4), newAStringLiteralExp(inLoopAndMessage.getValue() + " %d "),
                            arrayGet(fixedStepStatus, newAIdentifierExp((LexIdentifier) compIndexVar.clone())))),
                    newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE)),
                            newABoolLiteralExp(false))));

            if (inLoopAndMessage.getKey()) {
                body.add(newBreak());
            }

            list.getValue().add(newIf(newOr((newEqual(getCompStatusExp.apply(list.getKey()), newAIntLiteralExp(FMI_ERROR))),
                    (newEqual(getCompStatusExp.apply(list.getKey()), newAIntLiteralExp(FMI_FATAL)))), newABlockStm(body), null));
        };

        Consumer> terminate = list -> {
            list.addAll(componentNames.stream().map(comp -> newExpressionStm(
                    newACallExp(newAIdentifierExp((LexIdentifier) comp.clone()), newAIdentifier("terminate"), Collections.emptyList())))
                    .collect(Collectors.toList()));
        };


        Consumer> doStep = (list) -> componentNames.forEach(comp -> {
            //int doStep(real currentCommunicationPoint, real communicationStepSize, bool noSetFMUStatePriorToCurrentPoint);
            list.add(newAAssignmentStm(getCompStatusDesignator.apply(comp),
                    newACallExp(newAIdentifierExp((LexIdentifier) comp.clone()), newAIdentifier("doStep"),
                            Arrays.asList(newAIdentifierExp((LexIdentifier) time.clone()), newAIdentifierExp(fix_stepSize),
                                    newABoolLiteralExp(true)))));

            // checkStatusDoStep.accept(Map.entry(comp, list));
        });

        Consumer> progressTime = list -> list.add(newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) time.clone()),
                newPlusExp(newAIdentifierExp((LexIdentifier) time.clone()), newAIdentifierExp(fix_stepSize))));


        StateHandler stateHandler = new StateHandler(componentNames, env, getCompStatusDesignator, checkStatus);

        DerivativesHandler derivativesHandler = new DerivativesHandler();

        DataExchangeHandler dataExchangeHandler = new DataExchangeHandler(relations, env, getCompStatusDesignator, checkStatus);
        DataWriterHandler dataWriter = new DataWriterHandler();
        List dataWriterAllocateStms =
                dataWriter.allocate(dataExchangeHandler.getInputRelations(), dataExchangeHandler.getOutputs(), unitRelationShip);


        Consumer> handleDoStepStatuses = list -> {

            list.add(newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) fixedStepOverallStatus.clone()), newABoolLiteralExp(true)));
            list.add(newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) compIndexVar.clone()), newAIntLiteralExp(0)));
            //check if all ok
            list.add(newWhile(newALessBinaryExp(newAIdentifierExp((LexIdentifier) compIndexVar.clone()), newAIntLiteralExp(componentNames.size())),
                    newABlockStm(Arrays.asList(

                            newIf(newNotEqual(arrayGet(newAIdentifierExp(fixedStepStatus), newAIdentifierExp((LexIdentifier) compIndexVar.clone())),
                                    newAIntLiteralExp(FMI_OK)), newABlockStm(Arrays.asList(
                                    newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) fixedStepOverallStatus.clone()),
                                            newABoolLiteralExp(false)),

                                    newExpressionStm(newACallExp(newAIdentifierExp("logger"), newAIdentifier("log"),
                                            Arrays.asList(newAIntLiteralExp(4), newAStringLiteralExp("doStep failed for %d - status code "),
                                                    newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                                            Arrays.asList(newAIdentifierExp((LexIdentifier) compIndexVar.clone()))))))


                                    , newBreak())), null),


                            newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) compIndexVar.clone()),
                                    newPlusExp(newAIdentifierExp((LexIdentifier) compIndexVar.clone()), newAIntLiteralExp(1)))


                    ))));


            list.add(newIf(newNot(newAIdentifierExp((LexIdentifier) fixedStepOverallStatus.clone())), newABlockStm(Arrays.asList(


                    newExpressionStm(newACallExp(newAIdentifierExp("logger"), newAIdentifier("log"),
                            Arrays.asList(newAIntLiteralExp(4), newAStringLiteralExp("Deviating from normal execution. Handling exceptions %d"),
                                    newAIntLiteralExp(0)))),


                    newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) fixedStepOverallStatus.clone()), newABoolLiteralExp(true)),
                    newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) compIndexVar.clone()), newAIntLiteralExp(0)),
                    newVariable("discardObserved", newABoleanPrimitiveType(), newABoolLiteralExp(false)),
                    //check if all ok
                    newWhile(newALessBinaryExp(newAIdentifierExp((LexIdentifier) compIndexVar.clone()), newAIntLiteralExp(componentNames.size())),
                            newABlockStm(Arrays.asList(

                                    newExpressionStm(newACallExp(newAIdentifierExp("logger"), newAIdentifier("log"),
                                            Arrays.asList(newAIntLiteralExp(4), newAStringLiteralExp("Fmu index %d, status code %d"),
                                                    newAIdentifierExp((LexIdentifier) compIndexVar.clone()),
                                                    arrayGet(fixedStepStatus, newAIdentifierExp((LexIdentifier) compIndexVar.clone()))))),

                                    newIf(newNotEqual(newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                            Arrays.asList(newAIdentifierExp((LexIdentifier) compIndexVar.clone()))), newAIntLiteralExp(FMI_OK)),
                                            newABlockStm(Arrays.asList(
                                                    newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) fixedStepOverallStatus.clone()),
                                                            newABoolLiteralExp(false)),

                                                    newIf(newEqual(newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                                            Arrays.asList(newAIdentifierExp((LexIdentifier) compIndexVar.clone()))),
                                                            newAIntLiteralExp(FMI_PENDING)), newExpressionStm(
                                                            newACallExp(newAIdentifierExp("logger"), newAIdentifier("log"),
                                                                    Arrays.asList(newAIntLiteralExp(4), newAStringLiteralExp(
                                                                            "doStep failed for %d PENDING not supported- " + "status code "),
                                                                            newAArrayIndexExp(newAIdentifierExp(fixedStepStatus), Arrays.asList(
                                                                                    newAIdentifierExp((LexIdentifier) compIndexVar.clone())))))),
                                                            newIf(newOr((newEqual(newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                                                    Arrays.asList(newAIdentifierExp((LexIdentifier) compIndexVar.clone()))),
                                                                    newAIntLiteralExp(FMI_ERROR))), (newEqual(
                                                                    newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                                                            Arrays.asList(newAIdentifierExp((LexIdentifier) compIndexVar.clone()))),
                                                                    newAIntLiteralExp(FMI_FATAL)))),

                                                                    newExpressionStm(newACallExp(newAIdentifierExp("logger"), newAIdentifier("log"),
                                                                            Arrays.asList(newAIntLiteralExp(4),
                                                                                    newAStringLiteralExp("doStep failed for %d - status code "),
                                                                                    newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                                                                            Arrays.asList(newAIdentifierExp(
                                                                                                    (LexIdentifier) compIndexVar.clone())))))),
                                                                    null)), newIf(newEqual(newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                                            Arrays.asList(newAIdentifierExp((LexIdentifier) compIndexVar.clone()))),
                                                            newAIntLiteralExp(FMI_DISCARD)), newABlockStm(newExpressionStm(
                                                            simLog(LogUtil.SimLogLevel.DEBUG, "Instance discarding %d",
                                                                    newAIdentifierExp((LexIdentifier) compIndexVar.clone()))),
                                                            newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier("discardObserved")),
                                                                    newABoolLiteralExp(true))

                                                    ), null)


                                                    , newAAssignmentStm(
                                                            newAIdentifierStateDesignator(newAIdentifier(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE)),
                                                            newABoolLiteralExp(false)), newBreak())), null),


                                    newAAssignmentStm(newAIdentifierStateDesignator((LexIdentifier) compIndexVar.clone()),
                                            newPlusExp(newAIdentifierExp((LexIdentifier) compIndexVar.clone()), newAIntLiteralExp(1)))


                            ))),


                    newIf(newNot(newAIdentifierExp(newAIdentifier(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE))),
                            !stateHandler.supportsGetSetState ? newBreak() : newIf(newAIdentifierExp("discardObserved"),

                                    new Supplier() {
                                        @Override
                                        public PStm get() {
                                            List list = new Vector<>();
                                            list.add(loopComponents(beforeList -> {
                                                beforeList.add(newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(fix_recoveryStepSize)),
                                                        newAIdentifierExp(newAIdentifier(fix_stepSize))));

                                                beforeList.add(newVariable("fix_recover_real_status", newARealNumericPrimitiveType(),
                                                        newARealLiteralExp(0d)));

                                            }, newAIdentifierExp(fixedStepStatus), newAIntLiteralExp(componentNames.size()), (index, comp) -> {

                                                return Arrays.asList(newIf(newEqual(newAArrayIndexExp(newAIdentifierExp(fixedStepStatus),
                                                        Arrays.asList(newAIdentifierExp((LexIdentifier) compIndexVar.clone()))),
                                                        newAIntLiteralExp(FMI_DISCARD)), newABlockStm(Arrays.asList(

                                                        newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(fix_recovering)),
                                                                newABoolLiteralExp(true)),

                                                        newAAssignmentStm(newAArayStateDesignator(
                                                                newAIdentifierStateDesignator(newAIdentifier(fixedStepStatus)),
                                                                newAIdentifierExp((LexIdentifier) compIndexVar.clone())),
                                                                call(arrayGet(componentsIdentifier,
                                                                        newAIdentifierExp((LexIdentifier) compIndexVar.clone())), "getRealStatus",
                                                                        newAIntLiteralExp(FMI_STATUS_LAST_SUCCESSFUL),
                                                                        newARefExp(newAIdentifierExp("fix_recover_real_status")))),
                                                        newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(fix_recoveryStepSize)),
                                                                call("math", "min", newAIdentifierExp(fix_recoveryStepSize),
                                                                        newMinusExp(newAIdentifierExp("fix_recover_real_status"),
                                                                                newAIdentifierExp("time")))), newExpressionStm(
                                                                simLog(LogUtil.SimLogLevel.DEBUG, "Recovery time set to: %f",
                                                                        newAIdentifierExp(fix_recoveryStepSize)))

                                                )), null), newExpressionStm(call(arrayGet(componentsIdentifier, index.clone()), "setState",
                                                        arrayGet(stateHandler.fix_comp_states, index.clone()))));


                                            }));
                                            list.addAll(stateHandler.freeAllStates());
                                            list.add(newAAssignmentStm(
                                                    newAIdentifierStateDesignator(newAIdentifier(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE)),
                                                    newABoolLiteralExp(true)));
                                            return newABlockStm(list);
                                        }
                                    }.get()


                                    , null), null), null)), null));


            //check for fatals


            //check for possible reduced stepping

        };
        List statements = new Vector<>();
        statements.addAll(derivativesHandler.allocateMemory(componentNames, dataExchangeHandler.getInputRelations(), unitRelationShip));


        List loopStmts = new Vector<>();
        //handle recovery
        loopStmts.add(newIf(newAIdentifierExp(fix_recovering), newABlockStm(
                Arrays.asList(newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(fix_stepSize)), newAIdentifierExp(fix_recoveryStepSize)),
                        newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(fix_recovering)), newABoolLiteralExp(false)))),
                newAAssignmentStm(newAIdentifierStateDesignator(newAIdentifier(fix_stepSize)), stepSize.clone())));


        //exchange according to mapping
        loopStmts.addAll(dataExchangeHandler.exchangeData());
        //set inputs
        loopStmts.addAll(dataExchangeHandler.setAll());
        loopStmts.addAll(derivativesHandler.set(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE));
        //get state
        loopStmts.addAll(stateHandler.getAllStates());
        //do step
        doStep.accept(loopStmts);
        //handle failures during stepping
        handleDoStepStatuses.accept(loopStmts);

        List loopStmtsPost = new Vector<>();

        //

        //get data
        loopStmtsPost.addAll(dataExchangeHandler.getAll(true));
        loopStmtsPost.addAll(derivativesHandler.get(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE));

        progressTime.accept(loopStmtsPost);
        loopStmtsPost.addAll(dataWriter.write());
        loopStmtsPost.addAll(stateHandler.freeAllStates());

        loopStmts.add(newIf(
                newAnd(newAIdentifierExp(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE), newNot(newAIdentifierExp(newAIdentifier(fix_recovering)))),
                newABlockStm(loopStmtsPost), null));


        //pre allocation
        statements.add(newVariable(end, newARealNumericPrimitiveType(), newMinusExp(endTime, stepSize)));
        statements.add(newVariable(time, newARealNumericPrimitiveType(), startTime));
        statements.add(newVariable(fix_stepSize, newARealNumericPrimitiveType(), newARealLiteralExp(0d)));
        statements.add(newVariable(fix_recoveryStepSize, newARealNumericPrimitiveType(), newARealLiteralExp(0d)));
        statements.add(newVariable(fix_recovering, newABoleanPrimitiveType(), newABoolLiteralExp(false)));
        statements.addAll(stateHandler.allocate());
        statements.add(newVariable(fixedStepOverallStatus, newABoleanPrimitiveType(), newABoolLiteralExp(false)));
        statements.add(newVariable(compIndexVar, newAIntNumericPrimitiveType(), newAIntLiteralExp(0)));
        statements.addAll(dataExchangeHandler.allocate());
        statements.add(newALocalVariableStm(
                newAVariableDeclaration(newAIdentifier(fixedStepStatus), newAArrayType(newAIntNumericPrimitiveType()), componentNames.size(),
                        newAArrayInitializer(
                                IntStream.range(0, componentNames.size()).mapToObj(i -> newAIntLiteralExp(0)).collect(Collectors.toList())))));
        // get prior to entering loop
        statements.addAll(dataExchangeHandler.getAll(false));

        statements.addAll(derivativesHandler.get(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE));
        statements.addAll(dataWriterAllocateStms);
        statements.addAll(dataWriter.write());
        //loop
        statements.add(newWhile(newAnd(newAIdentifierExp(IMaestroPlugin.GLOBAL_EXECUTION_CONTINUE),
                (newALessEqualBinaryExp(newAIdentifierExp(time), newAIdentifierExp(end)))), newABlockStm(loopStmts)));
        //post simulation
        terminate.accept(statements);
        statements.addAll(dataWriter.deallocate());
        statements.addAll(derivativesHandler.deallocate());
        //statements.add(newExpressionStm(newUnloadExp(Arrays.asList(newAIdentifierExp("logger")))));
        return Collections.singletonList(newABlockStm(statements));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy