예제 #1
0
    def test_step_size(self):

        # download the FMU and input file
        for filename in ['CoupledClutches.fmu', 'CoupledClutches_in.csv']:
            download_test_file('2.0', 'me', 'MapleSim', '2016.2', 'CoupledClutches', filename)

        # load the input
        input = np.genfromtxt('CoupledClutches_in.csv', delimiter=',', names=True)

        self.assertTrue(np.sum(input['time'] == 0.9) > 1, msg="Input event expected at t=0.9")

        start_time = 0.0
        stop_time = 1.5
        step_size = 1e-2
        output_interval = 2e-2
        T2 = 0.5

        # common arguments
        kwargs = {
            'filename': 'CoupledClutches.fmu',
            'start_time': start_time,
            'stop_time': stop_time,
            'fmi_type': 'ModelExchange',
            'step_size': step_size,
            'output_interval': output_interval,
            'input': input,
            'start_values': {'CoupledClutches1_T2': T2}
        }

        # fixed step w/o events
        result = simulate_fmu(solver='Euler', record_events=False, **kwargs)

        time = result['time']
        self.assertAlmostEqual(time[0], start_time, msg="First sample time must be equal to start_time")
        self.assertAlmostEqual(time[-1], stop_time, msg="Last sample time must be equal to stop_time")
        self.assertTrue(np.all(np.isclose(np.diff(time), output_interval)), msg="Output intervals must be regular")

        # fixed step w/ events
        result = simulate_fmu(solver='Euler', record_events=True, **kwargs)

        time = result['time']
        self.assertAlmostEqual(time[0], start_time, msg="First sample time must be equal to start_time")
        self.assertAlmostEqual(time[-1], stop_time, msg="Last sample time must be equal to stop_time")

        # variable step w/o events
        result = simulate_fmu(solver='CVode', record_events=False, **kwargs)

        time = result['time']
        self.assertAlmostEqual(time[0], start_time, msg="First sample time must be equal to start_time")
        self.assertAlmostEqual(time[-1], stop_time, msg="Last sample time must be equal to stop_time")
        self.assertTrue(np.all(np.isclose(np.diff(time), output_interval)), msg="Output intervals must be regular")

        # variable step w/ events
        result = simulate_fmu(solver='CVode', record_events=True, **kwargs)

        time = result['time']
        self.assertAlmostEqual(time[0], start_time, msg="First sample time must be equal to start_time")
        self.assertAlmostEqual(time[-1], stop_time, msg="Last sample time must be equal to stop_time")
        self.assertTrue(np.sum(time == 0.9) > 1, msg="Input event expected at t=0.9")
        self.assertTrue(np.sum(np.isclose(time, T2)) > 1, msg="Time event expected at t=T2")
    def test_get_directional_derivative(self):

        fmu_filename = 'Rectifier.fmu'

        download_test_file('2.0', 'CoSimulation', 'Dymola', '2017',
                           'Rectifier', fmu_filename)

        model_description = read_model_description(filename=fmu_filename)

        unzipdir = extract(fmu_filename)

        fmu = FMU2Slave(
            guid=model_description.guid,
            unzipDirectory=unzipdir,
            modelIdentifier=model_description.coSimulation.modelIdentifier)

        fmu.instantiate()
        fmu.setupExperiment()
        fmu.enterInitializationMode()

        # get the partial derivative for an initial unknown
        unknown = model_description.initialUnknowns[1]

        self.assertEqual('iAC[1]', unknown.variable.name)

        vrs_unknown = [unknown.variable.valueReference]
        vrs_known = [v.valueReference for v in unknown.dependencies]
        dv_known = [1.0] * len(unknown.dependencies)

        partial_der = fmu.getDirectionalDerivative(vUnknown_ref=vrs_unknown,
                                                   vKnown_ref=vrs_known,
                                                   dvKnown=dv_known)

        self.assertEqual([-2.0], partial_der)

        fmu.exitInitializationMode()

        # get the partial derivative for three output variables
        unknowns = model_description.outputs[4:7]

        self.assertEqual(['uAC[1]', 'uAC[2]', 'uAC[3]'],
                         [u.variable.name for u in unknowns])

        vrs_unknown = [u.variable.valueReference for u in unknowns]
        vrs_known = [v.valueReference for v in unknowns[0].dependencies]
        dv_known = [1.0] * len(vrs_known)

        partial_der = fmu.getDirectionalDerivative(vUnknown_ref=vrs_unknown,
                                                   vKnown_ref=vrs_known,
                                                   dvKnown=dv_known)

        self.assertAlmostEqual(-1500, partial_der[0])
        self.assertAlmostEqual(0, partial_der[1])
        self.assertAlmostEqual(1500, partial_der[2])

        fmu.terminate()
        fmu.freeInstance()
        rmtree(unzipdir)
예제 #3
0
 def setUpClass(cls):
     # download the FMU and input file
     download_test_file('2.0', 'ModelExchange', 'MapleSim', '2016.2',
                        'CoupledClutches', 'CoupledClutches.fmu')
     download_test_file('2.0', 'ModelExchange', 'MapleSim', '2016.2',
                        'CoupledClutches', 'CoupledClutches_in.csv')
     download_file(
         'https://github.com/modelica/fmi-cross-check/raw/master/fmus/2.0/me/win64/Dymola/2019FD01/Rectifier/Rectifier.fmu'
     )
예제 #4
0
    def test_cswrapper(self):

        filename = 'CoupledClutches.fmu'

        download_test_file('2.0', 'ModelExchange', 'MapleSim', '2016.2', 'CoupledClutches', filename)

        model_description = read_model_description(filename)

        self.assertIsNone(model_description.coSimulation)

        add_cswrapper(filename)

        simulate_fmu(filename, fmi_type='CoSimulation')
예제 #5
0
    def test_create_juypter_notebook(self):

        download_test_file('2.0', 'ModelExchange', 'MapleSim', '2016.2',
                           'CoupledClutches', 'CoupledClutches.fmu')

        create_jupyter_notebook('CoupledClutches.fmu')

        args = [
            'jupyter', 'nbconvert', '--to', 'notebook', '--execute',
            '--ExecutePreprocessor.timeout=60', '--output',
            'CoupledClutches_out.ipynb', 'CoupledClutches.ipynb'
        ]

        check_call(args)
예제 #6
0
    def test_serialize_fmu_state(self):

        fmu_filename = 'Rectifier.fmu'

        # download the FMU
        download_test_file('2.0', 'cs', 'MapleSim', '2016.2', 'Rectifier',
                           fmu_filename)

        # read the model description
        model_description = read_model_description(fmu_filename)

        # extract the FMU
        unzipdir = extract(fmu_filename)

        # instantiate the FMU
        fmu = FMU2Slave(
            guid=model_description.guid,
            unzipDirectory=unzipdir,
            modelIdentifier=model_description.coSimulation.modelIdentifier)

        # initialize
        fmu.instantiate()
        fmu.setupExperiment()
        fmu.enterInitializationMode()
        fmu.exitInitializationMode()

        # get the FMU state
        state = fmu.getFMUstate()

        # serialize the FMU state
        serialized_state = fmu.serializeFMUstate(state)

        # de-serialize the FMU state
        fmu.deSerializeFMUstate(serialized_state, state)

        # set the FMU state
        fmu.setFMUstate(state)

        # free the FMU state
        fmu.freeFMUstate(state)

        fmu.terminate()
        fmu.freeInstance()

        # clean up
        shutil.rmtree(unzipdir)
예제 #7
0
    def test_extracted_fmu(self):
        """ Simulate an extracted FMU """

        download_test_file('2.0', 'cs', 'MapleSim', '2016.2',
                           'CoupledClutches', 'CoupledClutches.fmu')

        # extract the FMU
        tempdir = extract('CoupledClutches.fmu')

        # load the model description before the simulation
        model_description = read_model_description(tempdir)

        result = simulate_fmu(tempdir, model_description=model_description)

        self.assertIsNotNone(result)

        # clean up
        shutil.rmtree(tempdir)
예제 #8
0
    def test_get_start_values(self):

        if platform.startswith('win'):
            fmi_versions = ['2.0']  # quick fix until FMUs are available
        elif platform.startswith(('darwin', 'linux')):
            fmi_versions = ['2.0']
        else:
            self.fail('Platform not supported')

        for fmi_version in fmi_versions:

            for fmi_type in ['CoSimulation', 'ModelExchange']:

                download_test_file(fmi_version, fmi_type, 'MapleSim', '2016.2',
                                   'CoupledClutches', 'CoupledClutches.fmu')

                start_values = get_start_values('CoupledClutches.fmu')

                self.assertEqual(start_values['CoupledClutches1_freqHz'],
                                 '0.2')
예제 #9
0
    def test_validate_start_values(self):

        filename = download_test_file('2.0', 'ModelExchange', 'MapleSim',
                                      '2016.2', 'CoupledClutches',
                                      'CoupledClutches.fmu')

        with self.assertRaises(Exception) as context:
            simulate_fmu(filename, start_values={'clutch1.sa': 0.0})

        self.assertEqual(
            'The start values for the following variables could not be set: clutch1.sa',
            str(context.exception))
예제 #10
0
def simulate_coupled_clutches(
        fmi_version='2.0',
        fmi_type='ModelExchange',
        output=['outputs[1]', 'outputs[2]', 'outputs[3]', 'outputs[4]'],
        solver='CVode',
        fmi_logging=False,
        show_plot=True):

    # download the FMU and input file
    for filename in ['CoupledClutches.fmu', 'CoupledClutches_in.csv']:
        download_test_file(fmi_version, fmi_type, 'MapleSim', '2016.2',
                           'CoupledClutches', filename)

    print("Loading input...")
    input = np.genfromtxt('CoupledClutches_in.csv', delimiter=',', names=True)

    print("Simulating CoupledClutches.fmu (FMI %s, %s, %s)..." %
          (fmi_version, fmi_type, solver))
    result = simulate_fmu(filename='CoupledClutches.fmu',
                          start_time=0,
                          stop_time=1.5,
                          solver=solver,
                          step_size=1e-2,
                          output_interval=2e-2,
                          start_values={'CoupledClutches1_freqHz': 0.4},
                          input=input,
                          output=output,
                          validate=False,
                          fmi_logging=fmi_logging)

    if show_plot:
        print("Plotting results...")
        from fmpy.util import plot_result
        plot_result(result=result,
                    window_title="CoupledClutches.fmu (FMI %s, %s, %s)" %
                    (fmi_version, fmi_type, solver))

    print("Done.")

    return result
예제 #11
0
파일: test_fmu_info.py 프로젝트: vruge/FMPy
 def setUpClass(cls):
     # download the FMU
     download_test_file('2.0', 'me', 'MapleSim', '2016.2', 'CoupledClutches', 'CoupledClutches.fmu')
예제 #12
0
 def setUpClass(cls):
     # download the FMU and input file
     download_test_file('2.0', 'ModelExchange', 'MapleSim', '2016.2', 'CoupledClutches', 'CoupledClutches.fmu')
     download_test_file('2.0', 'ModelExchange', 'MapleSim', '2016.2', 'CoupledClutches', 'CoupledClutches_in.csv')
예제 #13
0
def run_experiment(show_plot=True):

    if platform not in ['win32', 'win64']:
        raise Exception("Rectifier.fmu is only available for Windows")

    print("Parameter variation on %s:" % fmu_filename)
    print("  VAC", v_ac)
    print("  IDC", i_dc)

    if sync:
        dask.set_options(
            get=dask.dask.local.get_sync)  # synchronized scheduler

    # download the FMU
    download_test_file('2.0', 'CoSimulation', 'Dymola', '2017', 'Rectifier',
                       fmu_filename)

    # read the model description
    model_description = read_model_description(fmu_filename)

    # collect the value references for the variables to read / write
    vrs = {}
    for variable in model_description.modelVariables:
        vrs[variable.name] = variable.valueReference

    # extract the FMU
    unzipdir = fmpy.extract(fmu_filename)

    fmu_args = {
        'guid': model_description.guid,
        'modelIdentifier': model_description.coSimulation.modelIdentifier,
        'unzipDirectory': unzipdir
    }

    # get the value references for the start and output values
    start_vrs = [vrs['VAC'], vrs['IDC']]
    result_vrs = [vrs['uDC'], vrs['Losses']]

    indices = list(np.ndindex(I_DC.shape))

    chunks = []
    chunk_size = int(np.ceil(len(indices) / 10))

    # split the indices into 10 chunks
    for i in range(0, len(indices), chunk_size):
        chunks.append(
            [indices[i:i + chunk_size], fmu_args, start_vrs, result_vrs])

    print("Running %d simulations (%d chunks)..." % (V_AC.size, len(chunks)))
    with ProgressBar():
        # calculate the losses for every chunk
        results = bag.from_sequence(chunks).map(simulate_fmu).compute()

    LOSSES = np.zeros_like(V_AC)

    # put the results together
    for zipped, dll_handle in results:
        for i, res in zipped:
            LOSSES[i] = res[1]

    # unload the shared library
    if sync:
        while True:
            try:
                fmpy.freeLibrary(dll_handle)
            except:
                break

    # clean up
    shutil.rmtree(unzipdir)

    if show_plot:
        print("Plotting results...")

        import matplotlib.pyplot as plt

        figure = plt.figure()
        figure.patch.set_facecolor('white')
        ax = figure.add_subplot(1, 1, 1)

        CS = plt.contourf(V_AC, I_DC, LOSSES, 10)
        plt.colorbar(CS, aspect=30)

        CS = ax.contour(V_AC, I_DC, LOSSES, 10, colors='k', linewidths=0.8)
        ax.clabel(CS=CS, fmt='%.0f', fontsize=9, inline=1)

        ax.set_title('Losses / W')
        ax.set_xlabel('AC Voltage / V')
        ax.set_ylabel('DC Current / A')

        plt.show()
    else:
        print("Plotting disabled")

    print("Done.")

    return LOSSES
예제 #14
0
    def test_common_functions(self):

        if platform.startswith('win'):
            fmi_versions = ['1.0', '2.0']
        else:
            return

        for fmi_version in fmi_versions:

            model_name = 'BooleanNetwork1'
            filename = model_name + '.fmu'

            download_test_file(fmi_version, 'CoSimulation', 'Dymola', '2017', model_name, filename)

            model_description = read_model_description(filename)
            unzipdir = extract(filename)

            guid = model_description.guid

            variables = {}

            for v in model_description.modelVariables:
                variables[v.name] = v

            args = {
                'guid': guid,
                'modelIdentifier': model_description.coSimulation.modelIdentifier,
                'unzipDirectory': unzipdir,
                'instanceName': None
            }

            if fmi_version == '1.0':
                fmu = FMU1Slave(**args)
                fmu.instantiate("instance1")
                fmu.initialize()
            else:
                fmu = FMU2Slave(**args)
                fmu.instantiate(loggingOn=False)
                fmu.setupExperiment(tolerance=None)
                fmu.enterInitializationMode()
                fmu.exitInitializationMode()

            # get types platform
            types_platform = fmu.getTypesPlatform()

            if fmi_version == '1.0':
                self.assertEqual('standard32', types_platform)
            else:
                self.assertEqual('default', types_platform)

            # get FMI version
            version = fmu.getVersion()
            self.assertEqual(fmi_version, version)

            # set debug logging
            if fmi_version == '1.0':
                fmu.setDebugLogging(True)
            else:
                fmu.setDebugLogging(True, ['logAll'])

            # set and get Real
            vr = [variables['booleanPulse1.width'].valueReference]
            value = [30.0]
            fmu.setReal(vr, value)
            result = fmu.getReal(vr)
            self.assertTrue(result[0] == value[0])

            # set and get Integer
            vr = [variables['integerConstant.k'].valueReference]
            value = [-4]
            fmu.setInteger(vr, value)
            result = fmu.getInteger(vr)
            self.assertTrue(result[0] == value[0])

            # set and get Boolean
            vr = [variables['rSFlipFlop.Qini'].valueReference]
            value = [True]
            fmu.setBoolean(vr, value)
            result = fmu.getBoolean(vr)
            self.assertTrue(result[0] == value[0])

            # TODO: set and get String

            # clean up
            fmu.terminate()
            fmu.freeInstance()
            shutil.rmtree(unzipdir)
예제 #15
0
def simulate_custom_input(show_plot=True):

    # define the model name and simulation parameters
    fmu_filename = 'CoupledClutches.fmu'
    start_time = 0.0
    threshold = 2.0
    stop_time = 2.0
    step_size = 1e-3

    # download the FMU
    download_test_file('2.0', 'CoSimulation', 'MapleSim', '2016.2', 'CoupledClutches', fmu_filename)

    # read the model description
    model_description = read_model_description(fmu_filename)

    # collect the value references
    vrs = {}
    for variable in model_description.modelVariables:
        vrs[variable.name] = variable.valueReference

    # get the value references for the variables we want to get/set
    vr_inputs   = vrs['inputs']      # normalized force on the 3rd clutch
    vr_outputs4 = vrs['outputs[4]']  # angular velocity of the 4th inertia

    # extract the FMU
    unzipdir = extract(fmu_filename)

    fmu = FMU2Slave(guid=model_description.guid,
                    unzipDirectory=unzipdir,
                    modelIdentifier=model_description.coSimulation.modelIdentifier,
                    instanceName='instance1')

    # initialize
    fmu.instantiate()
    fmu.setupExperiment(startTime=start_time)
    fmu.enterInitializationMode()
    fmu.exitInitializationMode()

    time = start_time

    rows = []  # list to record the results

    # simulation loop
    while time < stop_time:

        # NOTE: the FMU.get*() and FMU.set*() functions take lists of
        # value references as arguments and return lists of values

        # set the input
        fmu.setReal([vr_inputs], [0.0 if time < 0.9 else 1.0])

        # perform one step
        fmu.doStep(currentCommunicationPoint=time, communicationStepSize=step_size)

        # get the values for 'inputs' and 'outputs[4]'
        inputs, outputs4 = fmu.getReal([vr_inputs, vr_outputs4])

        # use the threshold to terminate the simulation
        if outputs4 > threshold:
            print("Threshold reached at t = %g s" % time)
            break

        # append the results
        rows.append((time, inputs, outputs4))

        # advance the time
        time += step_size

    fmu.terminate()
    fmu.freeInstance()

    # clean up
    shutil.rmtree(unzipdir)

    # convert the results to a structured NumPy array
    result = np.array(rows, dtype=np.dtype([('time', np.float64), ('inputs', np.float64), ('outputs[4]', np.float64)]))

    # plot the results
    if show_plot:
        plot_result(result)

    return time
예제 #16
0
 def setUpClass(cls):
     # download the FMU
     download_test_file('2.0', 'ModelExchange', 'MapleSim', '2017',
                        'CoupledClutches', 'CoupledClutches.fmu')
예제 #17
0
 def setUpClass(cls):
     download_test_file('2.0', 'CoSimulation', 'Dymola', '2017',
                        'Rectifier', 'Rectifier.fmu')