Esempio n. 1
0
    def test_input_continuous(self):

        t = np.array( [ 0, 1, 2, 3])
        y = np.array([[ 0, 0, 3, 3],
                      [-1, 0, 1, 2]])

        # extrapolate left (hold)
        v1, v2 = Input.interpolate(-1, t, y)
        self.assertEqual(v1,  0)
        self.assertEqual(v2, -1)

        # hit sample
        v1, v2 = Input.interpolate(1, t, y)
        self.assertEqual(v1, 0)
        self.assertEqual(v2, 0)

        # interpolate (linear)
        v1, v2 = Input.interpolate(1.5, t, y)
        self.assertAlmostEqual(v1, 1.5)
        self.assertAlmostEqual(v2, 0.5)

        # extrapolate right (hold)
        v1, v2 = Input.interpolate(4, t, y)
        self.assertEqual(v1, 3)
        self.assertEqual(v2, 2)
Esempio n. 2
0
    def init(self):
        #self.set_inital_inputs({})
        self.input = Input(self.fmu, self.modelDescription, None)
        if self.is_fmi1:
            #            self.fmu.setTime(self.start_time)
            self.input.apply(0)
            self.fmu.initialize()
        else:
            #            self.fmu.setupExperiment(startTime=self.start_time)
            self.fmu.enterInitializationMode()
            self.input.apply(0)
            self.fmu.exitInitializationMode()

            # event iteration
            self.fmu.eventInfo.newDiscreteStatesNeeded = fmi2True
            self.fmu.eventInfo.terminateSimulation = fmi2False

            while self.fmu.eventInfo.newDiscreteStatesNeeded == fmi2True and self.fmu.eventInfo.terminateSimulation == fmi2False:
                # update discrete states
                self.fmu.newDiscreteStates()

            self.fmu.enterContinuousTimeMode()
        #self.fmu.initialize()
        self.set_solver()
        self.t_next = self.start_time
Esempio n. 3
0
    def test_event_detection(self):

        fmx = sys.float_info.max

        # no event
        t = np.array([0.0, 1.0])
        self.assertEqual(fmx, Input.nextEvent(0.8, t), "Expecting no events")

        # time grid with events at 0.5 and 0.8
        t = np.array(
            [0.1, 0.2, 0.3, 0.4, 0.5, 0.5, 0.6, 0.7, 0.8, 0.8, 0.8, 0.9, 1.0])

        self.assertEqual(0.5, Input.nextEvent(0.0, t),
                         "Expecting first event before first sample")
        self.assertEqual(0.5, Input.nextEvent(0.2, t),
                         "Expecting first event before first event")
        self.assertEqual(0.8, Input.nextEvent(0.5, t),
                         "Expecting second event at first event")
        self.assertEqual(
            0.8, Input.nextEvent(0.6, t),
            "Expecting second event between first and second event")
        self.assertEqual(
            fmx, Input.nextEvent(0.8, t),
            "Expecting no more events after second (multi) event")
        self.assertEqual(fmx, Input.nextEvent(1.0, t),
                         "Expecting no more events after last event")
        self.assertEqual(fmx, Input.nextEvent(2.0, t),
                         "Expecting no more events after last sample")
Esempio n. 4
0
    def test_continuous_signal_events(self):

        dtype = np.dtype([('time', np.float64)])

        model_description = ModelDescription()

        # no event
        signals = np.array([(0,), (1,)], dtype=dtype)
        t_events = Input.findEvents(signals, model_description)
        self.assertEqual([inf], t_events)

        # time grid with events at 0.5 and 0.8
        signals = np.array(list(zip([0.1, 0.2, 0.3, 0.4, 0.5, 0.5, 0.6, 0.7, 0.8, 0.8, 0.8, 0.9, 1.0])), dtype=dtype)
        t_events = Input.findEvents(signals, model_description)
        self.assertTrue(np.all([0.5, 0.8, inf] == t_events))
Esempio n. 5
0
    def test_single_sample(self):
        t = np.array([0])
        y = np.array([2])

        # "interpolate" input with only one sample
        v = Input.interpolate(1, t, y)

        self.assertEqual(v,  2)
Esempio n. 6
0
    def setup(self):
        self.t_next = self.start_time
        if self.exist:
            self.unzipDir = self.fmu_location
        else:
            self.unzipDir = extract(self.fmu_location)
        self.modelDescription = read_model_description(self.fmu_location, validate=self.validate)
        self.is_fmi1 = self.modelDescription.fmiVersion == '1.0'
        
        logger = printLogMessage
        
        if self.is_fmi1:
            callbacks = fmi1CallbackFunctions()
            callbacks.logger = fmi1CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi1CallbackAllocateMemoryTYPE(allocateMemory)
            callbacks.freeMemory = fmi1CallbackFreeMemoryTYPE(freeMemory)
            callbacks.stepFinished = None
        else:
            callbacks = fmi2CallbackFunctions()
            callbacks.logger = fmi2CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi2CallbackAllocateMemoryTYPE(allocateMemory)
            callbacks.freeMemory = fmi2CallbackFreeMemoryTYPE(freeMemory)
        
        #define var values for input and output variables
        self.vrs = {}
        for variable in self.modelDescription.modelVariables:
            self.vrs[variable.name] = [variable.valueReference, variable.type]

            
        if self.is_fmi1:
            self.fmu = FMU1Slave(guid = self.modelDescription.guid,
                                 unzipDirectory=self.unzipDir,
                                 modelIdentifier=self.modelDescription.coSimulation.modelIdentifier,
                                 instanceName=self.instanceName)
            self.fmu.instantiate(functions=callbacks)
            
        else:
            self.fmu = FMU2Slave(guid = self.modelDescription.guid,
                     unzipDirectory=self.unzipDir,
                     modelIdentifier=self.modelDescription.coSimulation.modelIdentifier,
                     instanceName=self.instanceName)
            self.fmu.instantiate(callbacks=callbacks)
            self.fmu.setupExperiment(startTime=self.start_time, tolerance=self.tolerance)
        
        self.input = Input(self.fmu, self.modelDescription, None)
Esempio n. 7
0
    def test_input_discrete(self):

        t = np.array([0, 1, 1, 2])
        y = np.array([[0, 0, 3, 3]])

        # extrapolate left
        v = Input.interpolate(-1, t, y)
        self.assertEqual(v, 0)

        # hit sample
        v = Input.interpolate(0, t, y)
        self.assertEqual(v, 0)

        # interpolate
        v = Input.interpolate(0.5, t, y)
        self.assertEqual(v, 0)

        # before event
        v = Input.interpolate(1, t, y)
        self.assertEqual(v, 0)

        # after event
        v = Input.interpolate(1, t, y, after_event=True)
        self.assertEqual(v, 3)

        # extrapolate right
        v = Input.interpolate(0, t, y)
        self.assertEqual(v, 0)
Esempio n. 8
0
    def test_input_discrete(self):

        t = np.array([0, 1, 1, 1, 2])
        y = np.array([[0, 0, 4, 3, 3]])

        # extrapolate left
        v = Input.interpolate(-1, t, y)
        self.assertEqual(v, 0, "Expecting first value")

        # hit sample
        v = Input.interpolate(0, t, y)
        self.assertEqual(v, 0, "Expecting value at sample")

        # interpolate
        v = Input.interpolate(0.5, t, y)
        self.assertEqual(v, 0, "Expecting to hold previous value")

        # before event
        v = Input.interpolate(1, t, y)
        self.assertEqual(v, 0, "Expecting value before event")

        # after event
        v = Input.interpolate(1, t, y, after_event=True)
        self.assertEqual(v, 3, "Expecting value after event")

        # extrapolate right
        v = Input.interpolate(3, t, y)
        self.assertEqual(v, 3, "Expecting last value")
Esempio n. 9
0
    def test_input_continuous(self):

        t = np.array([0, 1, 2, 3])
        y = np.array([[0, 0, 3, 3], [-1, 0, 1, 2]])

        # extrapolate left (hold)
        (u1, u2), (du1, du2) = Input.interpolate(-1, t, y)
        self.assertTrue((u1, u2) == (0, -1))
        self.assertTrue((du1, du2) == (0, 0))

        # hit sample
        (u1, u2), (du1, du2) = Input.interpolate(1, t, y)
        self.assertTrue((u1, u2) == (0, 0))
        self.assertTrue((du1, du2) == (0, 1))

        # interpolate (linear)
        (u1, u2), (du1, du2) = Input.interpolate(1.5, t, y)
        self.assertTrue((u1, u2) == (1.5, 0.5))
        self.assertTrue((du1, du2) == (3, 1))

        # extrapolate right (hold)
        (u1, u2), (du1, du2) = Input.interpolate(4, t, y)
        self.assertTrue((u1, u2) == (3, 2))
        self.assertTrue((du1, du2) == (0, 0))
Esempio n. 10
0
    def test_discrete_signal_events(self):

        # model with one discrete variable 'x'
        model_description = ModelDescription()
        variable = ScalarVariable('x', 0)
        variable.variability = 'discrete'
        model_description.modelVariables.append(variable)

        # discrete events at 0.1 and 0.4
        signals = np.array([(0.0, 0), (0.1, 0), (0.2, 1), (0.3, 1), (0.4, 2)],
                           dtype=np.dtype([('time', np.float64),
                                           ('x', np.int)]))

        t_event = Input.findEvents(signals, model_description)

        self.assertTrue(np.all([0.2, 0.4, inf] == t_event))
Esempio n. 11
0
    def __init__(self, name, options):
        super().__init__(name, options)
        #        self.createFlexInputPin()
        #        self.createPin('out', VALUETYPES.REAL)

        self.firstRun = 1

        self.inType = VALUETYPES.REAL
        self.outType = VALUETYPES.REAL

        if options['dyn'] == "full":
            if options['inType'] == "const":
                self.inType = VALUETYPES.REAL
            elif options['inType'] == "variab":
                self.inType = VALUETYPES.VECTOR
            if options['outType'] == "const":
                self.outType = VALUETYPES.REAL
            elif options['outType'] == "variab":
                self.outType = VALUETYPES.VECTOR
        elif options['dyn'] == "step":
            self.inType = VALUETYPES.REAL
            self.outType = VALUETYPES.REAL
        else:
            Exception('Error! FMPY.init(): Unsupported value for "dyn".')

        if 'fmu' in options:
            self.myFMUid = options['fmu']
        else:
            self.myFMUid = options['model_path'] + '\\' + options[
                'model'] + '.fmu'
        if 'interval' in options:
            if 'Tstart' in options['interval']:
                self.Tstart = options['interval']['Tstart']
            else:
                self.Tstart = 0.0
            self.time = self.Tstart
            if 'Tstep' in options[
                    'interval'] and options['interval']['Tstep'] > 0:
                self.Tstep = options['interval']['Tstep']
            elif 'Tstop' in options['interval']:
                if options['interval']['Tstop'] - self.Tstart > 0:
                    self.Tstep = options['interval']['Tstop'] - self.Tstart
                else:
                    Exception(
                        'Error! FMPY.init(): Tstop must be greater than Tstart.'
                    )
            else:
                Exception(
                    'Step size Tstep must be specified and greater than 0.')
            if 'Tstop' in options[
                    'interval'] and options['interval']['Tstep'] > self.Tstart:
                self.Tstop = options['interval']['Tstop']
            elif 'Tstep' in options['interval']:
                if options['interval']['Tstep'] > 0:
                    self.Tstop = options['interval']['Tstep']
                else:
                    Exception('Tstep must be positive.')
            else:
                Exception(
                    'Stop time Tstop must be specified and greater than start time.'
                )
        else:
            Exception('Interval for dynamic simulation must be specified.')

        if 'solOpt' in options:
            if 'Timeout' in options['interval']:
                self.Timeout = options['interval']['Timeout']
            else:
                self.Timeout = 100
            if 'Tolerance' in options['interval']:
                self.Tolerance = options['interval']['Tolerance']
            else:
                self.Tolerance = 1e-06

        self.t_next = self.Tstart

        self.FMUinput = []
        self.FMUoutput = []

        self.modelDescription = read_model_description(self.myFMUid,
                                                       validate=True)
        self.unzipdir = extract(
            self.myFMUid)  # is this one needed or I can delete it

        logger = printLogMessage

        callbacks = None
        if options['fmu_ver'] == 1:
            callbacks = fmi1CallbackFunctions()
            callbacks.logger = fmi1CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi1CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi1CallbackFreeMemoryTYPE(freeMemory)
            callbacks.stepFinished = None
        elif options['fmu_ver'] == 2:
            callbacks = fmi2CallbackFunctions()
            callbacks.logger = fmi2CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi2CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi2CallbackFreeMemoryTYPE(freeMemory)
        else:
            Exception("Please provide an existing FMU version")

        self.vrs = {}
        for variable in self.modelDescription.modelVariables:
            self.vrs[variable.name] = variable.valueReference

#        tIPSL = IPSLtranslator(self.modelDescription.modelVariables)

        self.FMUoutput = []
        for i in self.options['outputs']:
            self.FMUoutput.append(self.vrs[i])
            self.createPin('out', self.outType, i)

        self.FMUinput = []
        for i in self.options['inputs']:
            self.FMUinput.append(self.vrs[i])
            self.createPin('in', self.inType, i)

        self.FMUinit = []
        for i in self.options['x0']:
            self.FMUinit.append(self.vrs[i])
            self.createPin('in', self.inType, i, "init")
            self.setInputCondition("edge{" + i + "}", 'init')

        if options['type'] == 'CS':
            if options['fmu_ver'] == 1:
                self.myFMU = FMU1Slave(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       coSimulation.modelIdentifier,
                                       instanceName=options['model'])
                self.myFMU.instantiate(functions=callbacks)

            elif options['fmu_ver'] == 2:
                self.myFMU = FMU2Slave(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       coSimulation.modelIdentifier,
                                       instanceName=options['model'])
                self.myFMU.instantiate(callbacks=callbacks)
                self.myFMU.setupExperiment(startTime=self.Tstart,
                                           tolerance=self.Tolerance)
            else:
                Exception("Please provide an existing FMU version")

        elif options['type'] == 'ME':
            if options['fmu_ver'] == 1:
                self.myFMU = FMU1Model(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       modelExchange.modelIdentifier,
                                       instanceName=options['model'])
                # instantiate FMU
                self.myFMU.instantiate(functions=callbacks)
                self.myFMU.setTime(self.Tstart)
            elif options['fmu_ver'] == 2:
                self.myFMU = FMU2Model(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       modelExchange.modelIdentifier,
                                       instanceName=options['model'])
                # instantiate FMU
                self.myFMU.instantiate(callbacks=callbacks)
                self.myFMU.setupExperiment(startTime=self.Tstart)
            else:
                Exception("Please provide an existing FMU version")

            if 'fixedStep' in options['solOpt']:
                self.fixed_step = options['solOpt']['fixedStep']
            else:
                self.fixed_step = False

        self.inEvent = FMPYinput(self.myFMU, self.modelDescription, None)
Esempio n. 12
0
class FMPY(Element):
    def __init__(self, name, options):
        super().__init__(name, options)
        #        self.createFlexInputPin()
        #        self.createPin('out', VALUETYPES.REAL)

        self.firstRun = 1

        self.inType = VALUETYPES.REAL
        self.outType = VALUETYPES.REAL

        if options['dyn'] == "full":
            if options['inType'] == "const":
                self.inType = VALUETYPES.REAL
            elif options['inType'] == "variab":
                self.inType = VALUETYPES.VECTOR
            if options['outType'] == "const":
                self.outType = VALUETYPES.REAL
            elif options['outType'] == "variab":
                self.outType = VALUETYPES.VECTOR
        elif options['dyn'] == "step":
            self.inType = VALUETYPES.REAL
            self.outType = VALUETYPES.REAL
        else:
            Exception('Error! FMPY.init(): Unsupported value for "dyn".')

        if 'fmu' in options:
            self.myFMUid = options['fmu']
        else:
            self.myFMUid = options['model_path'] + '\\' + options[
                'model'] + '.fmu'
        if 'interval' in options:
            if 'Tstart' in options['interval']:
                self.Tstart = options['interval']['Tstart']
            else:
                self.Tstart = 0.0
            self.time = self.Tstart
            if 'Tstep' in options[
                    'interval'] and options['interval']['Tstep'] > 0:
                self.Tstep = options['interval']['Tstep']
            elif 'Tstop' in options['interval']:
                if options['interval']['Tstop'] - self.Tstart > 0:
                    self.Tstep = options['interval']['Tstop'] - self.Tstart
                else:
                    Exception(
                        'Error! FMPY.init(): Tstop must be greater than Tstart.'
                    )
            else:
                Exception(
                    'Step size Tstep must be specified and greater than 0.')
            if 'Tstop' in options[
                    'interval'] and options['interval']['Tstep'] > self.Tstart:
                self.Tstop = options['interval']['Tstop']
            elif 'Tstep' in options['interval']:
                if options['interval']['Tstep'] > 0:
                    self.Tstop = options['interval']['Tstep']
                else:
                    Exception('Tstep must be positive.')
            else:
                Exception(
                    'Stop time Tstop must be specified and greater than start time.'
                )
        else:
            Exception('Interval for dynamic simulation must be specified.')

        if 'solOpt' in options:
            if 'Timeout' in options['interval']:
                self.Timeout = options['interval']['Timeout']
            else:
                self.Timeout = 100
            if 'Tolerance' in options['interval']:
                self.Tolerance = options['interval']['Tolerance']
            else:
                self.Tolerance = 1e-06

        self.t_next = self.Tstart

        self.FMUinput = []
        self.FMUoutput = []

        self.modelDescription = read_model_description(self.myFMUid,
                                                       validate=True)
        self.unzipdir = extract(
            self.myFMUid)  # is this one needed or I can delete it

        logger = printLogMessage

        callbacks = None
        if options['fmu_ver'] == 1:
            callbacks = fmi1CallbackFunctions()
            callbacks.logger = fmi1CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi1CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi1CallbackFreeMemoryTYPE(freeMemory)
            callbacks.stepFinished = None
        elif options['fmu_ver'] == 2:
            callbacks = fmi2CallbackFunctions()
            callbacks.logger = fmi2CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi2CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi2CallbackFreeMemoryTYPE(freeMemory)
        else:
            Exception("Please provide an existing FMU version")

        self.vrs = {}
        for variable in self.modelDescription.modelVariables:
            self.vrs[variable.name] = variable.valueReference

#        tIPSL = IPSLtranslator(self.modelDescription.modelVariables)

        self.FMUoutput = []
        for i in self.options['outputs']:
            self.FMUoutput.append(self.vrs[i])
            self.createPin('out', self.outType, i)

        self.FMUinput = []
        for i in self.options['inputs']:
            self.FMUinput.append(self.vrs[i])
            self.createPin('in', self.inType, i)

        self.FMUinit = []
        for i in self.options['x0']:
            self.FMUinit.append(self.vrs[i])
            self.createPin('in', self.inType, i, "init")
            self.setInputCondition("edge{" + i + "}", 'init')

        if options['type'] == 'CS':
            if options['fmu_ver'] == 1:
                self.myFMU = FMU1Slave(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       coSimulation.modelIdentifier,
                                       instanceName=options['model'])
                self.myFMU.instantiate(functions=callbacks)

            elif options['fmu_ver'] == 2:
                self.myFMU = FMU2Slave(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       coSimulation.modelIdentifier,
                                       instanceName=options['model'])
                self.myFMU.instantiate(callbacks=callbacks)
                self.myFMU.setupExperiment(startTime=self.Tstart,
                                           tolerance=self.Tolerance)
            else:
                Exception("Please provide an existing FMU version")

        elif options['type'] == 'ME':
            if options['fmu_ver'] == 1:
                self.myFMU = FMU1Model(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       modelExchange.modelIdentifier,
                                       instanceName=options['model'])
                # instantiate FMU
                self.myFMU.instantiate(functions=callbacks)
                self.myFMU.setTime(self.Tstart)
            elif options['fmu_ver'] == 2:
                self.myFMU = FMU2Model(guid=self.modelDescription.guid,
                                       unzipDirectory=self.unzipdir,
                                       modelIdentifier=self.modelDescription.
                                       modelExchange.modelIdentifier,
                                       instanceName=options['model'])
                # instantiate FMU
                self.myFMU.instantiate(callbacks=callbacks)
                self.myFMU.setupExperiment(startTime=self.Tstart)
            else:
                Exception("Please provide an existing FMU version")

            if 'fixedStep' in options['solOpt']:
                self.fixed_step = options['solOpt']['fixedStep']
            else:
                self.fixed_step = False

        self.inEvent = FMPYinput(self.myFMU, self.modelDescription, None)

    def doFunc(self):

        inputValues = []
        FMUinputRefs = []
        if self.inType == VALUETYPES.REAL:
            #            for i in range(0, len(self.input)):
            #                if self.options['inmask'][i] == 0:  # The mask vector is used to separate initialization inputs (inmask=1) from regular causality="input" (inmask=0)
            for i in range(0, len(self.options['inputs'])):
                inputValues.append(self.input[i]['value'])
                FMUinputRefs.append(self.FMUinput[i])

        else:
            print(
                "This function is not supported yet!"
            )  # figure out how to initialize fmu when the entire input vector is given

        self.myFMU.setReal(list(FMUinputRefs), list(inputValues))
        #        self.myFMU.setReal(list(self.FMUinput), list(inputValues))

        if self.options[
                'dyn'] == 'full':  #TODO: probably need to change all self.options['inputs'] into combination of self.options['inputs'] and self.options['x0']

            # setup the numpy format for specifying input variables
            dt = [('time', np.float64)]
            dt += zip(self.options['inputs'],
                      [np.float64] * len(self.options['inputs']))

            # print the numpy format for specifying input variables just to make sure it's ok
            print(dt)

            # assign the input to input variables
            #    pom = numpy.empty(len(inputValues),dtype=dt)
            if self.options['type'] == "ME":
                pom = numpy.empty(
                    2, dtype=dt
                )  # with ME it is necessary to assign first step value and last step value
                pom['time'] = [self.Tstart, self.Tstop]
            elif self.options['type'] == 'CS':
                pom = numpy.empty(
                    1, dtype=dt
                )  # with CS it is necessary just to assign one value for the entire period
                pom['time'] = self.Tstart

            for i in range(0, len(self.options['inputs'])):
                pom[self.options['inputs'][i]] = inputValues[
                    i]  # assign all input values, time has been assigned previously

            print(pom)
            inputValues = pom

            result = simulate_fmu(self.options['fmu'],
                                  start_time=self.Tstart,
                                  stop_time=self.Tstop,
                                  timeout=self.Timeout,
                                  step_size=self.Tstep,
                                  input=inputValues,
                                  output=self.options['outputs'])
            print("result of simulate_fmu is " + str(result))
            print("dtype is " + str(result.dtype))

            for i in range(0, len(self.options['outputs'])):
                pom = result[self.options['outputs'][i]]
                print(pom)
                if self.outType == VALUETYPES.REAL:
                    self.output[i]['value'] = pom[-1]
                elif self.outType == VALUETYPES.VECTOR:
                    self.output[i]['value'] = pom

        elif self.options['dyn'] == 'step':

            time = self.time
            if self.options['type'] == 'CS':
                self.inEvent.apply(time)
                self.myFMU.doStep(currentCommunicationPoint=time,
                                  communicationStepSize=self.Tstep)
                self.time += self.Tstep
            elif self.options['type'] == 'ME':
                eps = 1.0e-13
                # step ahead in time
                if self.fixed_step:
                    if time + self.Tstep < self.Tstop + eps:
                        self.t_next = time + self.Tstep
                        #            else:
                        #                break
                else:
                    if time + eps >= self.t_next:  # t_next has been reached
                        # integrate to the next grid point
                        self.t_next = round(
                            time / self.Tstep) * self.Tstep + self.Tstep

                # gets the time of input event
                t_input_event = self.inEvent.apply(time)

                # check for input event
                input_event = t_input_event <= self.t_next

                if input_event:
                    self.t_next = t_input_event

                # check the time of next event.
                time_event = None
                if self.options['fmu_ver'] == 1:
                    time_event = self.myFMU.eventInfo.upcomingTimeEvent != fmi1False and self.myFMU.eventInfo.nextEventTime <= self.t_next
                elif self.options['fmu_ver'] == 2:
                    time_event = self.myFMU.eventInfo.nextEventTimeDefined != fmi2False and self.myFMU.eventInfo.nextEventTime <= self.t_next
                else:
                    Exception("Please provide an existing FMU version")

                if time_event and not self.fixed_step:
                    self.t_next = self.myFMU.eventInfo.nextEventTime

                state_event = None
                if self.t_next - time > eps:
                    # do one step
                    state_event, time = self.solver.step(time, self.t_next)
                else:
                    # skip
                    time = self.t_next

                # set the time
                self.myFMU.setTime(time)

                # check for step event, e.g.dynamic state selection
                step_event = None
                if self.options['fmu_ver'] == 1:
                    step_event = self.myFMU.completedIntegratorStep()
                elif self.options['fmu_ver'] == 2:
                    step_event, _ = self.myFMU.completedIntegratorStep()
                    step_event = step_event != fmi2False
                else:
                    Exception("Please provide an existing FMU version")

                # handle events
                if input_event or time_event or state_event or step_event:

                    # recorder.sample(time, force=True)

                    if input_event:
                        self.inEvent.apply(time=time, after_event=True)

                    # handle events
                    if self.options['fmu_ver'] == 1:
                        self.myFMU.eventUpdate()
                    elif self.options['fmu_ver'] == 2:
                        # handle events
                        self.myFMU.enterEventMode()

                        self.myFMU.eventInfo.newDiscreteStatesNeeded = fmi2True
                        self.myFMU.eventInfo.terminateSimulation = fmi2False

                        # update discrete states
                        while self.myFMU.eventInfo.newDiscreteStatesNeeded != fmi2False and self.myFMU.eventInfo.terminateSimulation == fmi2False:
                            self.myFMU.newDiscreteStates()

                        self.myFMU.enterContinuousTimeMode()
                    else:
                        Exception("Please provide an existing FMU version")

                    self.solver.reset(time)
            else:
                Exception("Please provide either 'ME' or 'CS' type.")

            pom = self.myFMU.getReal(list(self.FMUoutput))
            for i in range(0, len(self.FMUoutput)):
                self.output[i]['value'] = pom[i]

            print(pom)
        else:
            Exception(
                "Simulation option 'dyn' can be either 'step' or 'full'.")

    def compile(self):

        if self.firstRun == 0:
            inputValues = []
            FMUinputRefs = []
            if self.inType == VALUETYPES.REAL:
                #                for i in range(0, len(self.input)):
                #                    if self.options['inmask'][i] == 1:                      # The mask vector is used to separate initialization inputs (inmask=1) from regular causality="input" (inmask=0)
                for i in range(0, len(self.options['x0'])):
                    inputValues.append(
                        self.input[i + len(self.options['inputs'])]['value'])
                    FMUinputRefs.append(self.FMUinit[i])
            else:
                print(
                    "This function is not supported yet!"
                )  # figure out how to initialize fmu when the entire input vector is given

#            self.myFMU.setReal(list(self.FMUinput), list(inputValues))
            self.myFMU.setReal(list(FMUinputRefs), list(inputValues))

        self.firstRun -= 1
        if self.firstRun < 0:
            self.firstRun = 0

        self.time = self.Tstart
        self.t_next = self.Tstart
        self.myFMU.reset()

        if self.options['type'] == 'CS':
            if self.options['fmu_ver'] == 1:
                self.myFMU.initialize()
            elif self.options['fmu_ver'] == 2:
                self.myFMU.setupExperiment(startTime=self.Tstart,
                                           tolerance=self.Tolerance)
                self.myFMU.enterInitializationMode()
                self.myFMU.exitInitializationMode()
            else:
                Exception("Please provide an existing FMU version")

        elif self.options['type'] == 'ME':
            if self.options['fmu_ver'] == 1:
                self.myFMU.initialize()
            elif self.options['fmu_ver'] == 2:
                self.myFMU.setupExperiment(startTime=self.Tstart)
                self.myFMU.enterInitializationMode()
                self.myFMU.exitInitializationMode()

                # event iteration
                self.myFMU.eventInfo.newDiscreteStatesNeeded = fmi2True
                self.myFMU.eventInfo.terminateSimulation = fmi2False

                while self.myFMU.eventInfo.newDiscreteStatesNeeded == fmi2True and self.myFMU.eventInfo.terminateSimulation == fmi2False:
                    # update discrete states
                    self.myFMU.newDiscreteStates()

                self.myFMU.enterContinuousTimeMode()
                # self.fmu.initialize()
            else:
                Exception("Please provide an existing FMU version")

            solver_args = {
                'nx': self.modelDescription.numberOfContinuousStates,
                'nz': self.modelDescription.numberOfEventIndicators,
                'get_x': self.myFMU.getContinuousStates,
                'set_x': self.myFMU.setContinuousStates,
                'get_dx': self.myFMU.getDerivatives,
                'get_z': self.myFMU.getEventIndicators
            }

            if 'solver' in self.options['solOpt']:
                if self.options['solOpt']['solver'] == 'CVODE':
                    from fmpy.sundials import CVodeSolver
                    self.solver = CVodeSolver(
                        set_time=self.myFMU.setTime,
                        startTime=self.Tstart,
                        maxStep=(self.Tstop - self.Tstart) / 50.,
                        relativeTolerance=0.001,
                        **solver_args)

        else:
            Exception("Please provide either 'ME' or 'CS' type.")

    def decompile(self):
        self.firstRun = 1
        self.myFMU.terminate()
        self.myFMU.freeInstance()
        if self.options['type'] == 'ME':
            del self.solver
        shutil.rmtree(self.unzipdir)
Esempio n. 13
0
    def setup(self):
        fmi_call_logger = None
        self.t_next = self.start_time
        self.unzipDir = extract(self.fmu_location)
        self.modelDescription = read_model_description(self.fmu_location,
                                                       validate=self.validate)
        self.is_fmi1 = self.modelDescription.fmiVersion == '1.0'
        logger = printLogMessage
        # common FMU constructor arguments
        self.fmu_args = {
            'guid': self.modelDescription.guid,
            'unzipDirectory': self.unzipDir,
            'instanceName': self.instanceName,
            'fmiCallLogger': fmi_call_logger
        }

        if self.exist:

            from fmpy.util import compile_dll

            # compile the shared library from the C sources
            self.fmu_args['libraryPath'] = compile_dll(
                model_description=self.modelDescription,
                sources_dir=os.path.join(self.unzipDir, 'sources'))

        self.fmu_args[
            'modelIdentifier'] = self.modelDescription.modelExchange.modelIdentifier

        if self.is_fmi1:
            callbacks = fmi1CallbackFunctions()
            callbacks.logger = fmi1CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi1CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi1CallbackFreeMemoryTYPE(freeMemory)
            callbacks.stepFinished = None
        else:
            callbacks = fmi2CallbackFunctions()
            callbacks.logger = fmi2CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi2CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi2CallbackFreeMemoryTYPE(freeMemory)

        #define var values for input and output variables
        self.vrs = {}
        for variable in self.modelDescription.modelVariables:
            self.vrs[variable.name] = [variable.valueReference, variable.type]

        if self.is_fmi1:
            self.fmu = FMU1Model(guid=self.modelDescription.guid,
                                 unzipDirectory=self.unzipDir,
                                 modelIdentifier=self.modelDescription.
                                 modelExchange.modelIdentifier,
                                 instanceName=self.instanceName)
            #instantiate FMU
            self.fmu.instantiate(functions=callbacks)
            self.fmu.setTime(self.start_time)

        else:
            self.fmu = FMU2Model(guid=self.modelDescription.guid,
                                 unzipDirectory=self.unzipDir,
                                 modelIdentifier=self.modelDescription.
                                 modelExchange.modelIdentifier,
                                 instanceName=self.instanceName)
            #instantiate FMU
            self.fmu.instantiate(callbacks=callbacks)
            self.fmu.setupExperiment(startTime=self.start_time)

        self.input = Input(self.fmu, self.modelDescription, None)
Esempio n. 14
0
class FmuMeAdapter():
    '''
    FMU Model Exchange adapter for energysim
    '''
    def __init__(self,
                 fmu_location,
                 instanceName=None,
                 start_time=0,
                 tolerance=1e-06,
                 stop_time=100,
                 step_size=1.0e-3,
                 inputs=[],
                 outputs=[],
                 solver_name='Cvode',
                 show_fmu_info=False,
                 exist=False,
                 validate=True):

        assert (fmu_location is not None), "Must specify FMU location"
        self.fmu_location = fmu_location
        if instanceName is None:
            instanceID = int(random() * 1000)
            self.instanceName = 'fmu' + str(instanceID)
            print('FMU instance created as: ' + self.instanceName)
        else:
            self.instanceName = instanceName
        self.tolerance = tolerance
        self.start_time = start_time
        self.stop_time = stop_time
        self.step_size = step_size
        self.inputs = inputs
        self.outputs = outputs
        self.solver_name = solver_name
        self.validate = validate
        if show_fmu_info:
            dump(self.fmu_location)
        self.exist = exist
        self.setup()

    def setup(self):
        fmi_call_logger = None
        self.t_next = self.start_time
        self.unzipDir = extract(self.fmu_location)
        self.modelDescription = read_model_description(self.fmu_location,
                                                       validate=self.validate)
        self.is_fmi1 = self.modelDescription.fmiVersion == '1.0'
        logger = printLogMessage
        # common FMU constructor arguments
        self.fmu_args = {
            'guid': self.modelDescription.guid,
            'unzipDirectory': self.unzipDir,
            'instanceName': self.instanceName,
            'fmiCallLogger': fmi_call_logger
        }

        if self.exist:

            from fmpy.util import compile_dll

            # compile the shared library from the C sources
            self.fmu_args['libraryPath'] = compile_dll(
                model_description=self.modelDescription,
                sources_dir=os.path.join(self.unzipDir, 'sources'))

        self.fmu_args[
            'modelIdentifier'] = self.modelDescription.modelExchange.modelIdentifier

        if self.is_fmi1:
            callbacks = fmi1CallbackFunctions()
            callbacks.logger = fmi1CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi1CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi1CallbackFreeMemoryTYPE(freeMemory)
            callbacks.stepFinished = None
        else:
            callbacks = fmi2CallbackFunctions()
            callbacks.logger = fmi2CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi2CallbackAllocateMemoryTYPE(
                allocateMemory)
            callbacks.freeMemory = fmi2CallbackFreeMemoryTYPE(freeMemory)

        #define var values for input and output variables
        self.vrs = {}
        for variable in self.modelDescription.modelVariables:
            self.vrs[variable.name] = [variable.valueReference, variable.type]

        if self.is_fmi1:
            self.fmu = FMU1Model(guid=self.modelDescription.guid,
                                 unzipDirectory=self.unzipDir,
                                 modelIdentifier=self.modelDescription.
                                 modelExchange.modelIdentifier,
                                 instanceName=self.instanceName)
            #instantiate FMU
            self.fmu.instantiate(functions=callbacks)
            self.fmu.setTime(self.start_time)

        else:
            self.fmu = FMU2Model(guid=self.modelDescription.guid,
                                 unzipDirectory=self.unzipDir,
                                 modelIdentifier=self.modelDescription.
                                 modelExchange.modelIdentifier,
                                 instanceName=self.instanceName)
            #instantiate FMU
            self.fmu.instantiate(callbacks=callbacks)
            self.fmu.setupExperiment(startTime=self.start_time)

        self.input = Input(self.fmu, self.modelDescription, None)

    def set_start_values(self, init_dict):
        apply_start_values(self.fmu,
                           self.modelDescription,
                           init_dict,
                           apply_default_start_values=False)

    def set_value(self, parameterName, Value):
        '''
        Must specify parameters and values in list format
        '''
        for i, j in zip(parameterName, Value):
            if self.vrs[i][1] == 'Real':
                self.fmu.setReal([self.vrs[i][0]], [j])
            elif self.vrs[i][1] in ['Integer', 'Enumeration']:
                self.fmu.setInteger([self.vrs[i][0]], [j])
            elif self.vrs[i][1] == 'Boolean':
                if isinstance(j, str):
                    if j.lower() not in ['true', 'false']:
                        raise Exception(
                            'The value "%s" for variable "%s" could not be converted to Boolean'
                            % (j, i))
                    else:
                        j = j.lower() == 'true'
                self.fmu.setBoolean([self.vrs[i][0]], [bool(j)])
            elif self.vrs[i][1] == 'String':
                self.fmu.setString([self.vrs[i][0]], [j])

    def get_value(self, parameterName, time):
        '''
        Must specify parameter in a list format.
        '''
        values_ = []
        for i in parameterName:
            if self.vrs[i][1] == 'Real':
                temp = self.fmu.getReal([self.vrs[i][0]])
            elif self.vrs[i][1] in ['Integer', 'Enumeration']:
                temp = self.fmu.getInteger([self.vrs[i][0]])
            elif self.vrs[i][1] == 'Boolean':
                temp = self.fmu.getBoolean([self.vrs[i][0]])
            elif self.vrs[i][1] == 'String':
                temp = self.fmu.getString([self.vrs[i][0]])

            values_.append(temp[0])
#        values_ = self.fmu.getReal(list(self.parameterVar))
        return values_

    def reset(self):
        self.fmu.reset()

    def init(self):
        #self.set_inital_inputs({})
        self.input = Input(self.fmu, self.modelDescription, None)
        if self.is_fmi1:
            #            self.fmu.setTime(self.start_time)
            self.input.apply(0)
            self.fmu.initialize()
        else:
            #            self.fmu.setupExperiment(startTime=self.start_time)
            self.fmu.enterInitializationMode()
            self.input.apply(0)
            self.fmu.exitInitializationMode()

            # event iteration
            self.fmu.eventInfo.newDiscreteStatesNeeded = fmi2True
            self.fmu.eventInfo.terminateSimulation = fmi2False

            while self.fmu.eventInfo.newDiscreteStatesNeeded == fmi2True and self.fmu.eventInfo.terminateSimulation == fmi2False:
                # update discrete states
                self.fmu.newDiscreteStates()

            self.fmu.enterContinuousTimeMode()
        #self.fmu.initialize()
        self.set_solver()
        self.t_next = self.start_time

    def set_solver(self):
        solver_args = {
            'nx': self.modelDescription.numberOfContinuousStates,
            'nz': self.modelDescription.numberOfEventIndicators,
            'get_x': self.fmu.getContinuousStates,
            'set_x': self.fmu.setContinuousStates,
            'get_dx': self.fmu.getDerivatives,
            'get_z': self.fmu.getEventIndicators
        }

        if self.solver_name == 'Cvode':
            from fmpy.sundials import CVodeSolver
            self.solver = CVodeSolver(
                set_time=self.fmu.setTime,
                startTime=self.start_time,
                maxStep=(self.stop_time - self.start_time) / 50.,
                relativeTolerance=0.001,
                **solver_args)

            self.fixed_step = False

        if self.solver_name == 'Euler':
            self.solver = ForwardEuler(**solver_args)
            self.fixed_step = True

    def setInput(self, inputValues):
        self.inputVariables = []
        for i in self.inputs:
            self.inputVariables.append(self.vrs[i][0])
        self.fmu.setReal(list(self.inputVariables), list(inputValues))

    def getOutput(self):
        self.outputVariables = []
        for i in self.outputs:
            self.outputVariables.append(self.vrs[i][0])

        return self.fmu.getReal(list(self.outputVariables))

    def step(self, time, csStep=False):

        if csStep:
            print(
                'Variable step is only supported in cosimulation FMUs. Exiting simulation.'
            )
            sys.exit()

        eps = 1.0e-13
        #step ahead in time
        if self.fixed_step:
            if time + self.step_size < self.stop_time + eps:
                self.t_next = time + self.step_size
#            else:
#                break
        else:
            if time + eps >= self.t_next:  # t_next has been reached
                # integrate to the next grid point
                #                self.t_next = round(time / self.step_size) * self.step_size + self.step_size
                self.t_next = np.floor(
                    time / self.step_size) * self.step_size + self.step_size
                if self.t_next < time + eps:
                    self.t_next += self.step_size

        #gets the time of input event
        t_input_event = self.input.nextEvent(time)

        # check for input event
        input_event = t_input_event <= self.t_next

        if input_event:
            self.t_next = t_input_event

        #check the time of next event.
        if self.is_fmi1:
            time_event = self.fmu.eventInfo.upcomingTimeEvent != fmi1False and self.fmu.eventInfo.nextEventTime <= self.t_next
        else:
            time_event = self.fmu.eventInfo.nextEventTimeDefined != fmi2False and self.fmu.eventInfo.nextEventTime <= self.t_next

#        time_event = self.fmu.eventInfo.upcomingTimeEvent != fmi1False and self.fmu.eventInfo.nextEventTime <= self.t_next

        if time_event and not self.fixed_step:
            self.t_next = self.fmu.eventInfo.nextEventTime

        if self.t_next - time > eps:
            # do one step
            state_event, time = self.solver.step(time, self.t_next)
        else:
            # skip
            time = self.t_next
            state_event = False

        # set the time
        self.fmu.setTime(time)

        # check for step event, e.g.dynamic state selection
        if self.is_fmi1:
            step_event = self.fmu.completedIntegratorStep()
        else:
            step_event, _ = self.fmu.completedIntegratorStep()
            step_event = step_event != fmi2False

        # handle events
        if input_event or time_event or state_event or step_event:

            #recorder.sample(time, force=True)

            if input_event:
                input.apply(time=time, after_event=True)

            # handle events
            if self.is_fmi1:
                self.fmu.eventUpdate()
            else:
                # handle events
                self.fmu.enterEventMode()

                self.fmu.eventInfo.newDiscreteStatesNeeded = fmi2True
                self.fmu.eventInfo.terminateSimulation = fmi2False

                # update discrete states
                while self.fmu.eventInfo.newDiscreteStatesNeeded != fmi2False and self.fmu.eventInfo.terminateSimulation == fmi2False:
                    self.fmu.newDiscreteStates()

                self.fmu.enterContinuousTimeMode()

            self.solver.reset(time)

    def terminate(self):
        self.fmu.terminate()

    def cleanUp(self):
        self.fmu.terminate()
        self.fmu.freeInstance()
        del self.solver


#        shutil.rmtree(self.unzipDir)

    def simulate(self, timeout=180):
        from fmpy import simulate_fmu

        result = simulate_fmu(self.fmu_location,
                              start_time=self.start_time,
                              stop_time=self.stop_time,
                              timeout=timeout,
                              step_size=self.step_size,
                              output=self.outputs)
        return result
Esempio n. 15
0
class FmuCsAdapter():
    '''
    FMU CoSimulation adapter for energysim
    '''
    
    eps = 1.0e-13
    
    def __init__(self, fmu_location, 
                 instanceName=None, 
                 start_time=0, 
                 tolerance=1e-06, 
                 stop_time = 100, 
                 step_size = 1.0e-3, 
                 inputs = [], 
                 outputs = [],
                 show_fmu_info = False,
                 exist=False,
                 validate=True):
        assert (fmu_location is not None), "Must specify FMU location"
        self.fmu_location = fmu_location
        if instanceName is None:
            instanceID = int(random()*1000)
            self.instanceName = 'fmu'+str(instanceID)
            print(self.instanceName)
        else:
            self.instanceName = instanceName
        self.exist = exist
        self.tolerance = tolerance
        self.start_time = start_time
        self.stop_time = stop_time
        self.output_interval = step_size
        self.inputs = inputs
        self.outputs = outputs
        self.validate=validate
        if show_fmu_info:
            dump(self.fmu_location)
        self.setup()

        
    def setup(self):
        self.t_next = self.start_time
        if self.exist:
            self.unzipDir = self.fmu_location
        else:
            self.unzipDir = extract(self.fmu_location)
        self.modelDescription = read_model_description(self.fmu_location, validate=self.validate)
        self.is_fmi1 = self.modelDescription.fmiVersion == '1.0'
        
        logger = printLogMessage
        
        if self.is_fmi1:
            callbacks = fmi1CallbackFunctions()
            callbacks.logger = fmi1CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi1CallbackAllocateMemoryTYPE(allocateMemory)
            callbacks.freeMemory = fmi1CallbackFreeMemoryTYPE(freeMemory)
            callbacks.stepFinished = None
        else:
            callbacks = fmi2CallbackFunctions()
            callbacks.logger = fmi2CallbackLoggerTYPE(logger)
            callbacks.allocateMemory = fmi2CallbackAllocateMemoryTYPE(allocateMemory)
            callbacks.freeMemory = fmi2CallbackFreeMemoryTYPE(freeMemory)
        
        #define var values for input and output variables
        self.vrs = {}
        for variable in self.modelDescription.modelVariables:
            self.vrs[variable.name] = [variable.valueReference, variable.type]

            
        if self.is_fmi1:
            self.fmu = FMU1Slave(guid = self.modelDescription.guid,
                                 unzipDirectory=self.unzipDir,
                                 modelIdentifier=self.modelDescription.coSimulation.modelIdentifier,
                                 instanceName=self.instanceName)
            self.fmu.instantiate(functions=callbacks)
            
        else:
            self.fmu = FMU2Slave(guid = self.modelDescription.guid,
                     unzipDirectory=self.unzipDir,
                     modelIdentifier=self.modelDescription.coSimulation.modelIdentifier,
                     instanceName=self.instanceName)
            self.fmu.instantiate(callbacks=callbacks)
            self.fmu.setupExperiment(startTime=self.start_time, tolerance=self.tolerance)
        
        self.input = Input(self.fmu, self.modelDescription, None)
        
    def set_start_values(self, init_dict):
        apply_start_values(self.fmu, self.modelDescription, init_dict, apply_default_start_values=False)

    def set_value(self,parameterName,Value):
        '''
        Must specify parameters and values in list format
        '''
        for i, j in zip(parameterName, Value):
            
            if self.vrs[i][1] == 'Real':
                self.fmu.setReal([self.vrs[i][0]], [j])
            elif self.vrs[i][1] in ['Integer', 'Enumeration']:
                self.fmu.setInteger([self.vrs[i][0]], [j])
            elif self.vrs[i][1] == 'Boolean':
                if isinstance(j, str):
                    if j.lower() not in ['true', 'false']:
                        raise Exception('The value "%s" for variable "%s" could not be converted to Boolean' %
                                        (j, i))
                    else:
                        j = j.lower() == 'true'
                self.fmu.setBoolean([self.vrs[i][0]], [bool(j)])
            elif self.vrs[i][1] == 'String':
                self.fmu.setString([self.vrs[i][0]], [j])
    

    def get_value(self,parameterName, time):
        '''
        Must specify parameter in a list format.
        '''
        values_ = []
        for i in parameterName:
            if self.vrs[i][1] == 'Real':
                temp = self.fmu.getReal([self.vrs[i][0]])
            elif self.vrs[i][1] in ['Integer', 'Enumeration']:
                temp = self.fmu.getInteger([self.vrs[i][0]])
            elif self.vrs[i][1] == 'Boolean':
                temp = self.fmu.getBoolean([self.vrs[i][0]])
            elif self.vrs[i][1] == 'String':
                temp = self.fmu.getString([self.vrs[i][0]])
            
            values_.append(temp[0])
        return values_
        
    def reset(self):
        self.fmu.reset()
        
    def init(self): 
        if self.is_fmi1:
            #self.input.apply(0)
            self.fmu.initialize()
        else:
            self.fmu.enterInitializationMode()
            #input.apply(0)
            self.fmu.exitInitializationMode()
    
    
    def set_inital_inputs(self, starting_values):
        from fmpy.simulation import apply_start_values
        apply_start_values(fmu = self.fmu,
                           model_description = self.modelDescription,
                           start_values = starting_values,
                           apply_default_start_values=False)
        
    def setInput(self, inputValues):
        self.inputVariables = []
        for i in self.inputs:
            self.inputVariables.append(self.vrs[i][0])
        self.fmu.setReal(list(self.inputVariables), list(inputValues))
    
    def getOutput(self):
        self.outputVariables = []
        for i in self.outputs:
            self.outputVariables.append(self.vrs[i][0])
        
        return self.fmu.getReal(list(self.outputVariables))
            
    
    def step_advanced(self, time, step_size=None):        
        #step ahead in time
        self.input.apply(time)
        if step_size is None:
            self.fmu.doStep(currentCommunicationPoint = time, communicationStepSize = self.output_interval)
        else:
            self.fmu.doStep(currentCommunicationPoint = time, communicationStepSize = step_size)
# TODO -           while a!=0:
#                self.fmu.setFMUstate(state)
##                print(f"Didnt work with stepsize = {step_size}, new stepsize = {step_size/2}.")
#                step_size = step_size/2
#                a = self.fmu.doStep(currentCommunicationPoint = time, communicationStepSize = step_size)
#            self.fmu.freeFMUstate(state)                    
#            print(f'returning to master: status = {a}, step size = {step_size}.')
#        return a, step_size
    
    def step_v2(self,time, stepsize):
        self.input.apply(time)
        return self.fmu.doStep(currentCommunicationPoint = time, communicationStepSize = stepsize)
    
    def step(self, time):
        #step ahead in time
        self.input.apply(time)
        return self.fmu.doStep(currentCommunicationPoint = time, communicationStepSize = self.output_interval)
    
    def cleanUp(self):
        self.fmu.terminate()
        self.fmu.freeInstance()
        
#        shutil.rmtree(self.unzipDir)
    
    def simulate(self, timeout=180):
        from fmpy import simulate_fmu
            
        result = simulate_fmu(self.fmu_location, 
                              start_time = self.start_time, 
                              stop_time =self.stop_time, 
                              timeout = timeout, 
                              output_interval = self.output_interval, 
                              output = self.outputs)
        return result