def test_mpc(self): # Inputs t = np.arange(0, 3600 * 10, 3600) inp = pd.DataFrame(index=pd.Index(t, name='time'), columns=['q', 'Tout']) inp['q'] = np.full(t.size, 0) inp['Tout'] = np.full(t.size, 273.15) # Bounds ubounds = [(0., 4000.)] xbounds = [(293.15, 296.15)] # Initial state x0 = [293.65] # Optimization mpc = mshoot.MPCEmulation(emumod=self.model, cfun=cfun) u, xctr, xemu, yemu, uhist = mpc.optimize(model=self.model, inp_ctr=inp.copy(), inp_emu=inp.copy(), free=['q'], ubounds=ubounds, xbounds=xbounds, x0=x0, ynominal=[4000., 293.15], step=1, horizon=3) # ax = u.plot(title='u') # ax.set_ylim(0, 4000) # ax = xemu.plot(title='xemu') # ax.set_ylim(292.15, 296.15) # plt.show() # Assert the solution is correct self.assertLess(abs(xemu['heatCapacitor.T'].iloc[-1] - 293.15), 0.3) # Ideally, should be even closer # Validate emulation with optimized control inp['q'] = u['q'] yvld, xvld = self.model.simulate(inp, x0) # self.assertTrue(((yvld - yemu).abs() < 1e-3).all().all()) # Might not be true for FMUs * self.assertTrue(((xvld - xemu).abs() < 1e-3).all().all()) # Might not be true for FMUs *
u2 = np.sin(t / 86400. * 2. * np.pi) * 1000. + np.random.rand( 48) * 1000. - 500. # Noisy sinusoid inp = pd.DataFrame(index=pd.Index(t, name='time')) inp['u1'] = u1 inp['u2'] = u2 inp.plot() plt.show() # 5) Define bounds Tlo = np.where((t > 86400 / 2) & (t < 86400 * 1.5), 273.15 + 23, 273.15 + 17) Thi = 273.15 + 25 # 6) Instantiate MPCEmulation mpc = mshoot.MPCEmulation(model_emu, cfun) # 7) Optimize u, xctr, xemu, yemu, u_hist = mpc.optimize(model=model_ctr, inp_ctr=inp, inp_emu=inp, free=['u1'], ubounds=[(-1000, 1000)], xbounds=[(273.15, 333.15), (273.15, 333.15), (Tlo, Thi)], x0=[293.15, 293.15, 293.15], maxiter=20, ynominal=[293.15, 1000.], step=1, horizon=3)