Attempting to model thermal losses from a building, I have implemented the following code to run the model using a state-space equation. It seems to take in variables as expected from .csv files and arrange them into correctly formed matrices. However, it is returning "Exception: Data arrays must have the same length, and match time discretization in dynamic problems"
.
When trying to debug I printed all the matrices in the equations to see if they matched (see below). I feel like this should be easy to see but I don't know where I have gone wrong.
[[-9.15750916 9.15750916]
[-0.12465719 0.13056645]]
[[295]
[295]]
[[0.00000000e+00 7.38461538e+00 3.84615385e+00]
[5.90925744e-03 0.00000000e+00 0.00000000e+00]]
[[[21. 14. 23. 28. 19. ]]
[[ 1.5 1.2 1.4 1.7 2. ]]
[[ 0. 0. 0. 0. 0. ]]]
[[1 0]]
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# SYSTEM BOUNDARIES
comfort = {'Occupied': np.array([20, 24])+273.15, \
'Unoccupied': np.array([18, 26])+273.15}
build_type = {'detached':np.array([0.42,0.26,8.86,19.1,1.92]),\
'semi-detached':np.array([]),\
'end-terrace':np.array([]),\
'mid-terrace':np.array([]),\
'bungalow':np.array([]),\
'flat':np.array([])}
# get csv data
# datafile = ""
df = pd.read_csv(r"COP_test.csv")
# sort data by column names
x0 = np.array(df["Ta"]) # Ambient temp
x1 = np.array(df["Ih"]) # Solar radiation
x2 = np.array(df["Qo"]) # Additional heating influences
#GEKKO model and initialise model simulator
m = GEKKO(remote=False); m.options.IMODE=4
# Building temperature variables
T_int = m.FV(295, lb=18+273.15, ub=24+273.15)
T_wal = m.FV(295, lb=15+273.15, ub=30+273.15)
# independent variables
Q_ext = m.Array(m.Param,3); Q_ext[0].value=x0; Q_ext[1].value=x1; Q_ext[2].value=x2,
# building coefficients
R_int, C_int, R_wal, C_wal, gA = build_type[btype]
# Matrix equations
A = np.array([[-1/(R_int*C_int), 1/(R_int*C_int)],
[-1/(R_int*C_wal), -(-1/(R_wal*C_wal)-1/(R_int*C_wal))]])
Bc = 1/C_int
Bx = np.array([[0, gA/C_int, 1/C_int],
[1/(R_wal*C_wal), 0, 0]])
C = np.array([[1, 0]])
# [T_int.dt(), T_wal.dt()] = m.equations()
x, y, u = m.state_space(A,Bx,C,D=None,discrete=True)
# right now does not include Bc, could append into matrix Bx
u[0].value = np.array([[x0],[x1],[x2]])
x[0].value = np.array([[T_int],[T_wal]])
print(A, x[0].value, Bx, u[0].value, C, sep='\n')
m.time = np.linspace(0,24,len(x0)) # time points, ideally to have a reading every half hour
m.options.nodes = 4
m.solve() # (GUI=True)
The code needed some modifications to import the data but the model was good. The script was also missing the data file and the btype
variable. Here is some sample data for testing with data.csv
.
time,Ta,Ih,Qo
0,30,0,0
4,31,0,0
8,35,10,20
12,38,20,30
16,40,50,20
20,37,30,10
24,30,0,0
On future questions, please include a complete example. Here is the modified code. I've commented out the state constraints because those can lead to an infeasible solution. You also need to use m.options.NODES=2
for discrete state space models.
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# SYSTEM BOUNDARIES
comfort = {'Occupied': np.array([20, 24])+273.15, \
'Unoccupied': np.array([18, 26])+273.15}
build_type = {'detached':np.array([0.42,0.26,8.86,19.1,1.92]),\
'semi-detached':np.array([]),\
'end-terrace':np.array([]),\
'mid-terrace':np.array([]),\
'bungalow':np.array([]),\
'flat':np.array([])}
# get csv data
df = pd.read_csv(r"test.csv")
btype = 'detached'
#GEKKO model and initialise model simulator
m = GEKKO(remote=False); m.options.IMODE=4
T_int = m.FV(295, lb=18+273.15, ub=24+273.15)
T_wal = m.FV(295, lb=15+273.15, ub=30+273.15)
# building coefficients
R_int, C_int, R_wal, C_wal, gA = build_type[btype]
# Matrix equations
A = np.array([[-1/(R_int*C_int), 1/(R_int*C_int)],
[-1/(R_int*C_wal), -(-1/(R_wal*C_wal)-1/(R_int*C_wal))]])
Bc = 1/C_int
Bx = np.array([[0, gA/C_int, 1/C_int],
[1/(R_wal*C_wal), 0, 0]])
C = np.array([[1, 0]])
# State Space
x, y, u = m.state_space(A,Bx,C,D=None,discrete=True)
# right now does not include Bc, could append into matrix Bx
Ta,Ih,Qo = u
# Building temperature variables
T_int,T_wal = x
T_int.value = 295
T_wal.value = 295
# Bounds on states can make the problem infeasible
#T_int.lower = 18+273.15
#T_int.upper = 24+273.15
#T_wal.lower = 15+273.15
#T_wal.upper = 30+273.15
# steady-state initialization
#m.options.IMODE = 1
#m.solve() # (GUI=True)
# dynamic simulation
m.time = df['time'] # time points
m.options.nodes = 2 # must be 2 for discrete models
Ta.value = df["Ta"] # Ambient temp
Ih.value = df["Ih"] # Solar radiation
Qo.value = df["Qo"] # Additional heating influences
m.solve()
There are additional state space examples in the documentation, including a complete MPC application with an Arduino microcontroller.