Exercise: ParmEst#

In this exercise, you will practice using ParmEst to estimate four parameters (\(U_a\), \(U_b\), \(C_p^H\), \(C_p^S\)) in the TCLab model using the step test data. We previously estimated these parameters using the sine test data.

import sys

# If running on Google Colab, install Pyomo and Ipopt via IDAES
on_colab = "google.colab" in sys.modules
if on_colab:
    !wget "https://raw.githubusercontent.com/dowlinglab/pyomo-doe/main/notebooks/tclab_pyomo.py"
else:
    import os

    if "exercise_solutions" in os.getcwd():
        # Add the "notebooks" folder to the path
        # This is needed for running the solutions from a separate folder
        # You only need this if you run locally
        sys.path.append('../notebooks')

# import TCLab model, simulation, and data analysis functions
from tclab_pyomo import (
    TC_Lab_data,
    TC_Lab_experiment,
    extract_results,
    extract_plot_results,
)

# set default number of states in the TCLab model
number_tclab_states = 2

Load and explore experimental data (step test)#

import pandas as pd

if on_colab:
    file = "https://raw.githubusercontent.com/dowlinglab/pyomo-doe/main/data/tclab_step_test.csv"
else:
    file = '../data/tclab_step_test.csv'
df = pd.read_csv(file)
df.head()

Make two plots to visualize the temperature and heat power data as a function of time.

# Add your solution here
# Add your solution here

We’ll now store the data in this custom data class objective. This is a nice trick to help keep data organized, but it is NOT required to use ParmEst or Pyomo data. Alternatively, we could just use a pandas DataFrame.

tc_data = TC_Lab_data(
    name="Step Test for Heater 1",
    time=df['Time'].values,
    T1=df['T1'].values,
    u1=df['Q1'].values,
    P1=200,
    TS1_data=None,
    T2=df['T2'].values,
    u2=df['Q2'].values,
    P2=200,
    TS2_data=None,
    Tamb=df['T1'].values[0],
)

Our custom data class has a method to export the data as a Pandas Data Frame.

tc_data.to_data_frame().head()

Parameter estimation with ParmEst#

Now for the main event: performing nonlinear least squares with ParmEst.

import pyomo.contrib.parmest.parmest as parmest

# First, we define an Experiment object within parmest
# Add your solution here

# Since everything has been labeled properly in the Experiment object, we simply invoke
# parmest's Estimator function to estimate the parameters.
# Add your solution here
parmest_regression_results = extract_plot_results(
    tc_data, pest.ef_instance
)

Discussion: How do these results compare to our previous analysis?