Пример #1
0
    def update_device_data(self, device_type=None, device_id=None):
        self._device_type = device_type if device_type is not None else self._device_type or 'not_specified'
        self._device_id = device_id if device_id is not None else self._device_id

        if self._device_type in self._device_type_id_struct:
            _id_set = self._device_type_id_struct[self._device_type].id_set
            _id_list = self._device_type_id_struct[self._device_type].id_list
            if self.device_id in _id_set:
                raise ValueError(
                    "Agent with type:'{}' and device_id:'{}' already exists".
                    format(self._device_type, self.device_id))
            elif self.device_id is None:
                self._device_id = (_id_list[-1] + 1) if _id_list else 1

            _id_set.add(self._device_id)
            bisect.insort(_id_list, self._device_id)
        else:
            if self.device_id is None:
                self._device_id = 1
            self._device_type_id_struct[self._device_type] = StructDict(
                id_set=set(), id_list=[])
            self._device_type_id_struct[self._device_type].id_set.add(
                self._device_id)
            self._device_type_id_struct[self._device_type].id_list.append(
                self._device_id)
Пример #2
0
    def sim_step_k(self,
                   k,
                   x_k_struct=None,
                   omega_k_struct=None,
                   mld_numeric_k_struct=None,
                   solver=None,
                   step_state=True):

        x_k_struct = x_k_struct if x_k_struct is not None else dict.fromkeys(
            self.controllers, None)
        omega_k_struct = omega_k_struct if omega_k_struct is not None else (
            self.get_omega_tilde_k_act(k=k, N_tilde_or_struct=1))

        mld_numeric_k_struct = mld_numeric_k_struct if mld_numeric_k_struct is not None else (
            dict.fromkeys(self.controllers, None))

        sims_step_k_struct = StructDict()
        for cname, controller in self._controllers.items():
            sims_step_k_struct[cname] = controller.sim_step_k(
                k=k,
                x_k=x_k_struct[cname],
                omega_k=omega_k_struct[cname],
                mld_numeric_k=mld_numeric_k_struct[cname],
                solver=solver,
                step_state=step_state)

        return sims_step_k_struct
Пример #3
0
def get_expr_shapes(*exprs, get_max_dim=False):
    if not exprs:
        return None

    if isinstance(exprs[0], dict):
        shapes = StructDict({
            expr_id: get_expr_shape(expr)
            for expr_id, expr in exprs[0].items()
        })
    else:
        shapes = [get_expr_shape(expr) for expr in exprs]

    if get_max_dim:
        shapes = list(shapes.values()) if isinstance(shapes, dict) else shapes
        return tuple(np.maximum.reduce(shapes))
    else:
        return shapes
Пример #4
0
    def gen_optimization_vars(self, N_p=None, N_tilde=None,
                              mld_numeric_k: MldModel = None, mld_numeric_tilde=None,
                              mld_info_k: MldInfo = None):

        slack_names = mld_info_k._slack_var_names

        # extract variable matrix_types from mld mld_infos
        if mld_numeric_tilde:
            var_types_N_tilde = {
                var_name: (
                    np.vstack(
                        [mld_numeric_tilde[k].mld_info.get_var_type(var_name) for k in range(N_tilde)]
                    ) if mld_info_k.get_var_dim(var_name) else (
                        np.empty((0, mld_info_k.get_var_dim(var_name) * N_tilde), dtype=np.str))
                ) for var_name in self._controllable_vars
            }
        else:
            var_types_N_tilde = {
                var_name: (
                    np.tile(mld_info_k.get_var_type(var_name), (N_tilde, 1)))
                for var_name in self._controllable_vars
            }

        def to_bin_index(type_mat):
            return (list(map(tuple, np.argwhere(type_mat == 'b').tolist())))

        # generate individual variable tilde mats
        opt_var_N_tilde = {
            var_name: (
                cvx.Variable(var_type_mat.shape, boolean=to_bin_index(var_type_mat),
                             name="".join([var_name.capitalize(), '_var_N_tilde']),
                             nonneg=(var_name in slack_names or None)) if var_type_mat.size
                else np.empty((0, 1))
            ) for var_name, var_type_mat in var_types_N_tilde.items()
        }

        variables = StructDict({var_name: EvoVariableStruct() for var_name in self._optimization_vars})
        for var_name in self._controllable_vars:
            self._set_var_using_var_N_tilde(variable=variables[var_name],
                                            var_dim=mld_info_k.get_var_dim(var_name),
                                            var_N_tilde=opt_var_N_tilde[var_name],
                                            N_p=N_p, N_tilde=N_tilde)

        # add combined input variable tilde mat
        opt_var_mats_N_tilde = [variables[var_name].var_mat_N_tilde for var_name in self._controllable_vars if
                                mld_info_k.get_var_dim(var_name)]

        v_var_mat_N_tilde = cvx.vstack(opt_var_mats_N_tilde) if opt_var_mats_N_tilde else np.empty((0, N_tilde))
        self._set_var_using_var_mat_N_tilde(variable=variables['v'],
                                            var_dim=mld_info_k.nv,
                                            var_mat_N_tilde=v_var_mat_N_tilde,
                                            N_p=N_p, N_tilde=N_tilde)

        return variables
def get_actual_omega_dewh_profiles(actual_scenarios=None, N_h=1, size=1):
    if isinstance(actual_scenarios, pd.DataFrame):
        actual_scenarios = actual_scenarios.values
    _, num_scen = actual_scenarios.shape
    omega_dewh_profiles = StructDict()
    for i in range(1, N_h + 1):
        randstate = np.random.RandomState(seed=np.int32(i**2))
        profile = actual_scenarios[:,
                                   randstate.
                                   choice(num_scen, size=size, replace=False)]
        omega_dewh_profiles[i] = profile.reshape(-1, 1, order='F')
    return omega_dewh_profiles
Пример #6
0
    def _set_vars_k_neg1(self, variables_k_neg1_struct=None, N_p=None, N_tilde=None,
                         mld_numeric_k: MldModel = None, mld_numeric_tilde=None,
                         mld_info_k: MldInfo = None):

        variables_k_neg1_struct = variables_k_neg1_struct or self.VariablesStruct_k_neg1.fromkeys(self)
        variables_k_neg1_struct_update = StructDict()
        for var_name, variable in self.items():
            var_k_neg1_update = variables_k_neg1_struct.get(var_name,None)
            var_update = (
                self._process_parameter_update(name=var_name + "_k_neg1", parameter=variable.var_k_neg1,
                                               required_shape=(variable.var_dim, 1),
                                               new_value=var_k_neg1_update))
            if var_update is not None:
                variables_k_neg1_struct_update[var_name] = var_update

        return variables_k_neg1_struct_update if variables_k_neg1_struct_update else None
Пример #7
0
    def gen_state_output_vars(self, variables=None,
                              x_k=None, omega_tilde_k=None,
                              N_p=None, N_tilde=None,
                              mld_numeric_k: MldModel = None, mld_numeric_tilde=None,
                              mld_info_k: MldInfo = None):

        state_output_vars = StructDict({var_name: EvoVariableStruct() for var_name in self._state_output_vars})

        x_k = x_k if x_k is not None else self.x_k
        omega_tilde_k = omega_tilde_k if omega_tilde_k is not None else self.omega_tilde_k

        variables = variables or self

        if mld_info_k.nx:
            state_output_vars.x.var_N_tilde = (
                    matmul(self.mld_evo_matrices.state_input['Phi_x_N_tilde'], x_k) +
                    matmul(self.mld_evo_matrices.state_input['Gamma_v_N_tilde'], variables.v.var_N_tilde) +
                    matmul(self.mld_evo_matrices.state_input['Gamma_omega_N_tilde'], omega_tilde_k) +
                    self.mld_evo_matrices.state_input['Gamma_5_N_tilde']
            )
        else:
            state_output_vars.x.var_N_tilde = np.empty((0, 1))

        if mld_info_k.ny:
            state_output_vars.y.var_N_tilde = (
                    matmul(self.mld_evo_matrices.output['L_x_N_tilde'], x_k) +
                    matmul(self.mld_evo_matrices.output['L_v_N_tilde'], variables['v']['var_N_tilde']) +
                    matmul(self.mld_evo_matrices.output['L_omega_N_tilde'], omega_tilde_k) +
                    self.mld_evo_matrices.output['L_5_N_tilde']
            )
        else:
            state_output_vars.y.var_N_tilde = np.empty((0, 1))

        for var_name in self._state_output_vars:
            var_N_tilde = state_output_vars[var_name].var_N_tilde
            self._set_var_using_var_N_tilde(variable=state_output_vars[var_name],
                                            var_dim=mld_info_k.get_var_dim(var_name),
                                            var_N_tilde=var_N_tilde,
                                            N_p=N_p, N_tilde=N_tilde)

        return state_output_vars
def sim_mpc(N_p=1,
            sim_steps=1,
            soft_top_mult=10.0,
            soft_bot_mult=1.0,
            num_scenarios=20,
            N_sb_reduced=8,
            controllers=None,
            save_text_postfix=""):
    N_tilde = N_p + 1
    controllers = controllers or {}
    deterministic_struct = {
        cname: controller.is_deterministic
        for cname, controller in controllers.items()
    }

    for dev in itertools.chain([grid], grid.devices):
        dev.delete_all_controllers()

    for cname, controller in controllers.items():
        for dev in itertools.chain([grid], grid.devices):
            if isinstance(dev, DewhAgentMpc):
                if issubclass(controller.controller_type, MpcController):
                    dev.add_controller(cname,
                                       controller.controller_type,
                                       N_p=N_p)
                else:
                    dev.add_controller(cname,
                                       controller.controller_type,
                                       N_p=0,
                                       N_tilde=1)
            else:
                if issubclass(controller.controller_type, MpcController):
                    dev.add_controller(cname,
                                       controller.controller_type,
                                       N_p=N_p)
                else:
                    dev.add_controller(cname, NoController, N_p=0, N_tilde=1)

    for dev in grid.devices:
        if isinstance(dev, DewhAgentMpc):
            dev.x_k = get_dewh_random_initial_state(dev.device_id)

    total_cost_struct = StructDict({cname: 0 for cname in controllers})

    grid.build_grid(k=0, deterministic_or_struct=deterministic_struct)
    for k in range(0, sim_steps):
        st = time.time()
        prices_tilde = grid.get_price_tilde_k(k=k)

        for cname, controller in controllers.items():
            if issubclass(controller.controller_type, MpcController):
                for dev in itertools.chain([grid], grid.devices):
                    if isinstance(dev, DewhAgentMpc) and issubclass(
                            controller.controller_type, MpcController):
                        if cname.startswith('mpc'):
                            price_vec = prices_tilde[cname]
                            max_cost = np.sum(
                                price_vec) * dewh_param_struct.P_h_Nom
                            q_mu_top = max_cost * soft_top_mult
                            q_mu_bot = max_cost * soft_bot_mult
                            dev.set_device_objective_atoms(
                                controller_name=cname,
                                q_mu=np.hstack([q_mu_top,
                                                q_mu_bot]).ravel(order='c'))

                        if cname.startswith('mpc_sb'):
                            omega_tilde_scenarios = dev.get_omega_tilde_scenario(
                                k,
                                N_tilde=N_tilde,
                                num_scenarios=num_scenarios)
                            if cname == 'mpc_sb_reduced':
                                dev.controllers[cname].set_constraints(
                                    other_constraints=[
                                        dev.controllers[cname].
                                        gen_evo_constraints(
                                            N_tilde=N_sb_reduced,
                                            omega_scenarios_k=
                                            omega_tilde_scenarios)
                                    ])
                            elif cname == 'mpc_sb_full':
                                dev.controllers[cname].set_constraints(
                                    other_constraints=[
                                        dev.controllers[cname].
                                        gen_evo_constraints(
                                            omega_scenarios_k=
                                            omega_tilde_scenarios)
                                    ])

                        elif cname == 'mpc_minmax':
                            omega_min, omega_max = get_min_max_dhw_scenario(
                                k=k,
                                N_tilde=N_tilde,
                                min_dhw_day=min_dhw_day,
                                max_dhw_day=max_dhw_day)

                            min_cons = dev.controllers[
                                cname].gen_evo_constraints(
                                    N_tilde=N_tilde, omega_tilde_k=omega_min)

                            max_cons = dev.controllers[
                                cname].gen_evo_constraints(
                                    N_tilde=N_tilde, omega_tilde_k=omega_max)

                            dev.controllers[cname].set_constraints(
                                other_constraints=[min_cons, max_cons])
                    elif isinstance(dev, GridAgentMpc) and issubclass(
                            controller.controller_type, MpcController):
                        dev.controllers[cname].set_std_obj_atoms(
                            q_z=prices_tilde[cname])

        grid.build_grid(k=k, deterministic_or_struct=deterministic_struct)
        grid.solve_grid_mpc(k=k, verbose=False, TimeLimit=20, MIPGap=1e-2)
        print(f'k={k}, N_p={N_p}')
        print(f"Time to solve including data transfer:{time.time() - st}")
        l_sim = grid.sim_step_k(k=k)
        print(f"Total Looptime:{time.time() - st}")

        solve_times_struct = StructDict()
        for cname in controllers:
            total_cost_struct[cname] += grid.sim_logs[cname].get(k).cost
            solve_times_struct[cname] = (
                grid.sim_logs[cname].get(k).time_in_solver,
                grid.sim_logs[cname].get(k).time_solve_overall)
        print('Total_cost\n', total_cost_struct)
        print('Solve_times\n', solve_times_struct)
        print('\n')

    df_sim: pd.DataFrame = grid.grid_sim_dataframe
    df_sim.index = pd.date_range(start=time_0, periods=sim_steps, freq='15min')

    if save_text_postfix and not save_text_postfix.startswith('_'):
        save_text_postfix = '_' + save_text_postfix

    T_max = int(dewh_param_struct_adjusted.T_h_max)
    T_min = int(dewh_param_struct_adjusted.T_h_min)

    save_dir = fr'{BASE_FILE}/sim_out'
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    save_path = os.path.realpath(
        fr'{BASE_FILE}/sim_out/sim_Np_{N_p}_st_{int(soft_top_mult)}_sb_{int(soft_bot_mult)}_Ns_{num_scenarios}_'
        fr'Nsr_{N_sb_reduced}_Nh_{N_h}_Tmax_{T_max}_Tmin_{T_min}{save_text_postfix}.sim_out'
    )

    df_sim.to_pickle(save_path)
    return StructDict(df_sim=df_sim, locals_vars=locals())
resdAgent.set_omega_profile(omega_resd_profile)
grid.add_device(resdAgent)

################################

print(f"Time to create dewh's':{time.time() - st}")

ControllerClass = namedtuple('ControllerClass',
                             ['controller_type', 'is_deterministic'])
controllers_choices = StructDict({
    'mpc_pb':
    ControllerClass(MpcController, True),
    'mpc_ce':
    ControllerClass(MpcController, False),
    'mpc_sb_reduced':
    ControllerClass(MpcController, False),
    'mpc_sb_full':
    ControllerClass(MpcController, False),
    'mpc_minmax':
    ControllerClass(MpcController, False),
    'thermo':
    ControllerClass(DewhTheromstatController, False)
})


def sim_mpc(N_p=1,
            sim_steps=1,
            soft_top_mult=10.0,
            soft_bot_mult=1.0,
            num_scenarios=20,
            N_sb_reduced=8,
            controllers=None,
Пример #10
0
class Agent:
    _device_type_id_struct = StructDict()

    def __init__(self,
                 device_type=None,
                 device_id=None,
                 sim_model: MldSystemModel = ParNotSet,
                 control_model: MldSystemModel = ParNotSet):

        self._device_type = None
        self._device_id = None
        self._sim_model = None
        self._control_model = None

        self.update_device_data(device_type=device_type, device_id=device_id)
        self.update_models(sim_model=sim_model, control_model=control_model)

    # todo Still needs work
    @classmethod
    def delete_all_devices(cls):
        cls._device_type_id_struct.clear()

    def update_device_data(self, device_type=None, device_id=None):
        self._device_type = device_type if device_type is not None else self._device_type or 'not_specified'
        self._device_id = device_id if device_id is not None else self._device_id

        if self._device_type in self._device_type_id_struct:
            _id_set = self._device_type_id_struct[self._device_type].id_set
            _id_list = self._device_type_id_struct[self._device_type].id_list
            if self.device_id in _id_set:
                raise ValueError(
                    "Agent with type:'{}' and device_id:'{}' already exists".
                    format(self._device_type, self.device_id))
            elif self.device_id is None:
                self._device_id = (_id_list[-1] + 1) if _id_list else 1

            _id_set.add(self._device_id)
            bisect.insort(_id_list, self._device_id)
        else:
            if self.device_id is None:
                self._device_id = 1
            self._device_type_id_struct[self._device_type] = StructDict(
                id_set=set(), id_list=[])
            self._device_type_id_struct[self._device_type].id_set.add(
                self._device_id)
            self._device_type_id_struct[self._device_type].id_list.append(
                self._device_id)

    def update_models(self,
                      sim_model: MldSystemModel = ParNotSet,
                      control_model: MldSystemModel = ParNotSet):

        if is_all_None(self._sim_model, self._control_model, sim_model,
                       control_model):
            self._sim_model = MldSystemModel()
            self._control_model = None
        else:
            self._sim_model = sim_model if sim_model is not ParNotSet else self._sim_model or MldSystemModel(
            )
            self._control_model = control_model if control_model is not ParNotSet else self._control_model or None

    # todo think about cleanup
    def __del__(self):
        # print("deleting")
        for col in self._device_type_id_struct[self._device_type].values():
            try:
                col.remove(self._device_id)
            except Exception:
                pass

    @property
    def device_type(self):
        return self._device_type

    @property
    def device_id(self):
        return self._device_id

    @property
    def sim_model(self) -> MldSystemModel:
        return self._sim_model

    @property
    def control_model(self) -> MldSystemModel:
        return self._control_model if self._control_model is not None else self._sim_model

    @property
    def mld_numeric(self) -> MldModel:
        return self._sim_model._mld_numeric

    @property
    def mld_info(self) -> MldInfo:
        return self.mld_numeric.mld_info

    @property
    def mld_numeric_tilde(self):
        return None

    @_recursive_repr()
    def __repr__(self):
        repr_dict = OrderedDict(device_type=self.device_type,
                                device_id=self.device_id,
                                sim_model=self.sim_model,
                                control_model=self.control_model)
        return struct_repr(repr_dict, type_name=self.__class__.__name__)
Пример #11
0
 def get_variables_k_act(self, k):
     return StructDict({
         controller_name: controller.sim_log.get(k)
         for controller_name, controller in self._controllers
     })
Пример #12
0
 def sim_logs(self) -> MutableMapping[AnyStr, MldSimLog]:
     return StructDict({
         controller_name: controller.sim_log
         for controller_name, controller in self._controllers.items()
     })
Пример #13
0
import numpy as np

__all__ = ['dewh_param_struct', 'grid_param_struct']

control_ts = TimeDelta(minutes=15)

#150L
dewh_param_struct = StructDict(
    C_w=4.1816 * 10 ** 3,  # J/kg/K
    A_h=2.35,  # m^2
    U_h=0.88,  # W/m^2/K
    m_h=150.0,  # kg
    T_w=15.0,  # C
    T_inf=25.0 ,  # C
    P_h_Nom=3000.0,  # W  (Joules/s)
    T_h_min=50.0,  # C
    T_h_max=65.0,  # C
    T_h_Nom=45.0, # C
    T_h_max_sub_T_h_on = 12,
    T_h_max_sub_T_h_off = 4,
    T_h = 45.0, #C
    D_h=0.0,  # kg/s
    control_ts=control_ts,
    ts=control_ts.seconds,
)

# # #250L
# dewh_param_struct = StructDict(
#     C_w=4.1816 * 10 ** 3,  # J/kg/K
#     A_h=3.22,#2.35,  # m^2
#     U_h=0.88,  # W/m^2/K
#     m_h=250,#150.0,  # kg