Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor new examples #4

Merged
merged 8 commits into from
Sep 29, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/00-evaluate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Twin evaluation examples
=======================
These examples show how to use the evaluation workflow on twins. This includes simple evaluation workflow, as well as parametric applications for static and dynamic models.
189 changes: 189 additions & 0 deletions examples/00-evaluate/coupledClutches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
"""pyTwin: Twin evaluation example --------------------------------------- This example shows how you can use pyTwin
to load and evaluate a Twin model. The model consists in a coupled clutches with 4 inputs (applied torque,
3 clutches opening) and 3 outputs (computed torque on each of the clutches) """

###############################################################################
# Perform required imports
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Perform required imports, which includes downloading and importing the input files
import csv
import platform

import matplotlib.pyplot as plt
import os
import pandas as pd
from src.ansys.twin.evaluate.evaluate import TwinModel
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
from src.ansys.twin import examples

twin_model = examples.download_file("CoupledClutches_23R1_other.twin", "twin_files")
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
csv_input = examples.download_file("CoupledClutches_input.csv", "twin_input_files")
twin_config = examples.download_file("CoupledClutches_config.json", "twin_input_files") # We will try to locate
# the model_setup, which provides default model start and parameter values override
cur_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))


###############################################################################
# Auxiliary functions definition
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Definition of load_data function (loading Twin inputs data from CSV file) and plot_result_comparison for
# post processing the results

def load_data(inputs: str):
"""Load a CSV input file into a Pandas Dataframe. Inputs is the path of the CSV file to be loaded,
containing the Time column and all the Twin inputs data"""

# Clean CSV headers if exported from Twin builder
def clean_column_names(column_names):
for name_index in range(len(column_names)):
clean_header = column_names[name_index].replace("\"", "").replace(" ", "").replace("]", "").replace("[", "")
name_components = clean_header.split(".", 1)
# The column name should match the last word after the "." in each column
column_names[name_index] = name_components[-1]

return column_names

# #### Data loading (into Pandas DataFrame) and pre-processing ###### #
# C engine can't read rows with quotes, reading just the first row
input_header_df = pd.read_csv(inputs, header=None, nrows=1, sep=r',\s+',
engine='python', quoting=csv.QUOTE_ALL)

# Reading all values from the csv but skipping the first row
inputs_df = pd.read_csv(inputs, header=None, skiprows=1)
inputs_header_values = input_header_df.iloc[0][0].split(',')
clean_column_names(inputs_header_values)
inputs_df.columns = inputs_header_values

return inputs_df


def plot_result_comparison(step_by_step_results: pd.DataFrame, batch_results: pd.DataFrame):
"""Compare the results obtained from 2 different simulations executed on the same TwinModel.
The 2 results dataset are provided as Pandas Dataframe. The function will plot the different results for all the
outputs and save the plot as a file "results.png" """
pd.set_option('display.precision', 12)
pd.set_option('display.max_columns', 20)
pd.set_option('display.expand_frame_repr', False)

# Plotting the runtime outputs
columns = step_by_step_results.columns[1::]
result_sets = 2 # Results from only step-by-step, batch_mode
fig, ax = plt.subplots(ncols=result_sets, nrows=len(columns), figsize=(18, 7))
if len(columns) == 1:
single_column = True
else:
single_column = False

fig.subplots_adjust(hspace=0.5)
fig.set_tight_layout({"pad": .0})
# x_data = runtime_result_df.iloc[:, 0]

for ind, col_name in enumerate(columns):
# Plot runtime results
if single_column:
axes0 = ax[0]
axes1 = ax[1]

else:
axes0 = ax[ind, 0]
axes1 = ax[ind, 1]

step_by_step_results.plot(x=0, y=col_name, ax=axes0, ls=":", color='g',
title='Twin Runtime - Step by Step')
axes0.legend(loc=2)
axes0.set_xlabel('Time [s]')

# Plot Twin batch mode csv results
batch_results.plot(x=0, y=col_name, ax=axes1, ls="-.", color='g',
title='Twin Runtime - Batch Mode')
axes1.legend(loc=2)
axes1.set_xlabel('Time [s]')

if ind > 0:
axes0.set_title('')
axes1.set_title('')

# Show plot
plt.style.use('seaborn')
plt.show()
plt.savefig(os.path.join(cur_dir, 'results.png'))


###############################################################################
# Defining external files path
# ~~~~~~~~~~~~~~~~~~~
# Defining the runtime log path as well as loading the input data


runtime_log = os.path.join(cur_dir, 'model_{}.log'.format(platform.system()))
twin_model_input_df = load_data(csv_input)
data_dimensions = twin_model_input_df.shape
number_of_datapoints = data_dimensions[0] - 1

###############################################################################
# Loading the Twin Runtime and instantiating it
# ~~~~~~~~~~~~~~~~~~~
# Loading the Twin Runtime and instantiating it.


print('Loading model: {}'.format(twin_model))
twin_runtime = TwinModel(twin_model)
chrpetre marked this conversation as resolved.
Show resolved Hide resolved

###############################################################################
# Setting up the initial settings of the Twin and initializing it
# ~~~~~~~~~~~~~~~~~~~
# Defining the initial inputs of the Twin, initializing it and collecting the initial outputs values


data_index = 0
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
inputs = dict()
for column in twin_model_input_df.columns[1::]:
inputs[column] = twin_model_input_df[column][data_index]
twin_runtime.initialize_evaluation(inputs=inputs, json_config_filepath=twin_config)
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
outputs = [twin_runtime.evaluation_time]
for item in twin_runtime.outputs:
outputs.append(twin_runtime.outputs[item])

###############################################################################
# Step by step simulation mode
# ~~~~~~~~~~~~~~~~~~~
# Looping over all the input data, simulating the Twin one time step at a time and collecting corresponding outputs


sim_output_list_step = [outputs]
while data_index < number_of_datapoints:
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
# Gets the stop time of the current simulation step
time_end = twin_model_input_df.iloc[data_index + 1][0]
step = time_end - twin_runtime.evaluation_time
inputs = dict()
for column in twin_model_input_df.columns[1::]:
inputs[column] = twin_model_input_df[column][data_index]
twin_runtime.evaluate_step_by_step(step_size=step, inputs=inputs)
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
outputs = [twin_runtime.evaluation_time]
for item in twin_runtime.outputs:
outputs.append(twin_runtime.outputs[item])
sim_output_list_step.append(outputs)
data_index += 1
results_step_pd = pd.DataFrame(sim_output_list_step, columns=['Time'] + list(twin_runtime.outputs),
dtype=float)

# ############################################################################## Batch simulation mode
# ~~~~~~~~~~~~~~~~~~~ Resetting/re-initializing the Twin and running it in batch mode (i.e. passing all the input
# data, simulating all the data points, and collecting all the outputs at once)


data_index = 0
inputs = dict()
for column in twin_model_input_df.columns[1::]:
inputs[column] = twin_model_input_df[column][data_index]
twin_runtime.initialize_evaluation(inputs=inputs, json_config_filepath=twin_config)
outputs = [twin_runtime.evaluation_time]
for item in twin_runtime.outputs:
outputs.append(twin_runtime.outputs[item])
results_batch_pd = twin_runtime.evaluate_batch(twin_model_input_df)

###############################################################################
# Post processing
# ~~~~~~~~~~~~~~~~~~~
# Plotting the different results and saving the image on disk

plot_result_comparison(results_step_pd, results_batch_pd)
Binary file added examples/00-evaluate/results.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
143 changes: 143 additions & 0 deletions examples/01-parametric-twin/electricRange.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
"""pyTwin: parametric Twin evaluation example --------------------------------------- This example shows how you can
use pyTwin to load and evaluate a Twin model and simulate multiple parametric variations. The model is used for
determining the range of an electric vehicle. The vehicle is represented by a battery, the electric loads of the
vehicle, and an electric machine connected to a simple 1D chassis. The driver controls the vehicle speed to follow a
repeated sequence of the WLTP cycle (class 3). The mass of the vehicle as well as the electric power loads are
parameterized so that we can see their effects on the overall eletric range """

###############################################################################
# Perform required imports
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Perform required imports, which includes downloading and importing the input files

import platform

import matplotlib.pyplot as plt
import os
import pandas as pd
from src.ansys.twin.evaluate.evaluate import TwinModel
from src.ansys.twin import examples

twin_model = examples.download_file("ElectricRangeCS_23R1_other.twin", "twin_files")
cur_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))

###############################################################################
# User inputs
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Defining user inputs and simulation settings

time_step = 1.0
time_end = 24000.0 # simulating the model for 400 minutes
dp1 = {"ElectricRange_powerLoad":2000.0, "ElectricRange_vehicleMass":2000.0}
dp2 = {"ElectricRange_powerLoad":3000.0, "ElectricRange_vehicleMass":2000.0}
dp3 = {"ElectricRange_powerLoad":2000.0, "ElectricRange_vehicleMass":1500.0}
sweep = [dp1, dp2, dp3]

###############################################################################
# Auxiliary functions definition
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Definition of load_data function (loading Twin inputs data from CSV file) and plot_result_comparison for
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
# post processing the results

def plot_result_comparison(results: list[pd.DataFrame], sweep: list[dict]):
"""Compare the results obtained from the different parametric simulations executed on the same TwinModel. The
results dataset are provided as Pandas Dataframe. The function will plot the different results for few particular
variables of interest and save the plot as a file "results.png" """
pd.set_option('display.precision', 12)
pd.set_option('display.max_columns', 20)
pd.set_option('display.expand_frame_repr', False)

color = ['g','b','r']
# output ordering : time, battery_loss, loads_loss, machine_loss, pack_SoC, position, speed_m, speed_ref,
# tau_ref, tau_sns
x0_ind = 0
y0_ind = 6
z0_ind = 7
x1_ind = 4
y1_ind = 5

# Plotting the runtime outputs
# We will plot 3 different results with all the parametric variations
fig, ax = plt.subplots(ncols=1, nrows=2, figsize=(18, 7))

fig.subplots_adjust(hspace=0.5)
fig.set_tight_layout({"pad": .0})

axes0 = ax[0]

results[0].plot(x=x0_ind, y=y0_ind, ax=axes0, label='{}'.format('measured speed'))
results[0].plot(x=x0_ind, y=z0_ind, ax=axes0, ls='-.', label='{}'.format('reference speed'))

axes0.set_title('Drive cycle')
axes0.set_xlabel(results[0].columns[x0_ind]+' [sec]')
axes0.set_ylabel(results[0].columns[y0_ind]+' [m/s]')
axes0.set_xlim((0, 32*60))

axes1 = ax[1]

for ind, dp in enumerate(sweep):
# Plot runtime results
results[ind].plot(x=x1_ind, y=y1_ind, ax=axes1, color=color[ind], label='{}'.format(dp))

axes1.set_title('Range/distance achieved vs battery SoC')
axes1.set_xlabel(results[0].columns[x1_ind])
axes1.set_xlim((0.1, 0.9))
axes1.set_ylabel(results[0].columns[y1_ind]+' [m]')

# Show plot
plt.style.use('seaborn')
plt.show()
plt.savefig(os.path.join(cur_dir, 'results.png'))


###############################################################################
# Defining external files path
# ~~~~~~~~~~~~~~~~~~~
# Defining the runtime log path as well as loading the input data


runtime_log = os.path.join(cur_dir, 'model_{}.log'.format(platform.system()))

###############################################################################
# Loading the Twin Runtime and instantiating it
# ~~~~~~~~~~~~~~~~~~~
# Loading the Twin Runtime and instantiating it.


print('Loading model: {}'.format(twin_model))
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
twin_runtime = TwinModel(twin_model)

###############################################################################
# Parametric sweep over the different design points
# ~~~~~~~~~~~~~~~~~~~
# Simulating the Twin for each set of parameters values, one time step at a time and collecting corresponding outputs

results = []
for dp in sweep:

# Twin initialization with the right parameters values and collection of initial outputs values
twin_runtime.initialize_evaluation(parameters=dp)
outputs = [twin_runtime.evaluation_time]
for item in twin_runtime.outputs:
outputs.append(twin_runtime.outputs[item])
sim_output = [outputs]
while twin_runtime.evaluation_time < time_end:
step = time_step
twin_runtime.evaluate_step_by_step(step_size=step)
outputs = [twin_runtime.evaluation_time]
for item in twin_runtime.outputs:
outputs.append(twin_runtime.outputs[item])
sim_output.append(outputs)
if twin_runtime.evaluation_time%1000 == 0.0:
print("Simulating the model with parameters {}, evaluation time = {}".format(dp,
twin_runtime.evaluation_time))
sim_results = pd.DataFrame(sim_output, columns=['Time'] + list(twin_runtime.outputs),
dtype=float)
results.append(sim_results)

###############################################################################
# Post processing
# ~~~~~~~~~~~~~~~~~~~
# Plotting the different results and saving the image on disk

plot_result_comparison(results, sweep)
Binary file added examples/01-parametric-twin/results.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/ansys/twin/examples/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .downloads import *
chrpetre marked this conversation as resolved.
Show resolved Hide resolved
Loading