n_segments = self.params['n_segments'].v()  # self.n_heat_exchanger
n_hex = range(1, n_segments + 1) #self.
self.n_hex = Set(initialize=n_hex)
self.TIME = Set(initialize=range(n_steps))
heat_profile = self.params['heat_profile']
def _heat_flow(b, t, c=None):
    return b.mult * heat_profile.v(t, c)
lines = self.params['lines'].v()               # done in fixedprofile
    self.block.temperatures = Var(lines, self.TIME) # for primary side               # done in fixedprofile
    self.block.temperature_hex_in = Var(self.TIME,self.n_hex) # clod/hot temperature along the h.ex # add in and out   #lines_ch
    self.block.temperature_hex_out = Var(self.TIME, self.n_hex)  # clod/hot temperature along the h.ex                  #lines_ch
    def _mass_flow(b, t, c=None):
        return abs(self.params['mass_flow'].v(t, c))
    if self.repr_days is None:
        self.block.mass_flow = Param(self.TIME,
                                     rule=_mass_flow,
                                     mutable=not self.temperature_driven)
        self.block.heat_flow = Param(self.TIME, rule=_heat_flow,
                                     mutable=not self.temperature_driven)
    else:
        self.block.mass_flow = Param(self.TIME, self.REPR_DAYS,
                                     rule=_mass_flow,
                                     mutable=not self.temperature_driven)
        self.block.heat_flow = Param(self.TIME, self.REPR_DAYS,
                                     rule=_heat_flow,
                                     mutable=not self.temperature_driven)
    ############# done in fixedprofile
    def _init_temperatures(b, l):
        return b.temperatures[l, 0] == self.params['temperature_' + l].v()
    self.block.init_temperatures = Constraint(lines, rule=_init_temperatures)
    #############
    #               boundary conditions for in / out temperatures of the first and last blocks
    def _decl_temperatures_in(b, t):
        return b.temperature_hex_in[t, 1] == b.temperatures['supply', t]
    self.block.decl_temperature_in = Constraint(self.TIME,
                                              rule=_decl_temperatures_in)
    def _decl_temperatures_out(b, t):
        return b.temperature_hex_out[t, n_segments] == b.temperatures['return', t]
    self.block.decl_temperature_out = Constraint(self.TIME,
                                              rule=_decl_temperatures_out)
    #############
    #                       temperature relationship between different blocks
    def _temp_blocks(b, t, n): #ch,
        if not n == n_segments:
            return b.temperature_hex_out[t, n] == b.temperature_hex_in[t, n + 1]
        else:
            return Constraint.Skip
    self.block.temp_blocks = Constraint(self.TIME, self.n_hex, rule=_temp_blocks) #lines_ch,
    # check to change, for loop doesn't work here! :(f
    def _decl_temperatures(b, t, n):
        if t==0:
            return Constraint.Skip
        elif b.mass_flow[t] == 0:
            return Constraint.Skip
        else: # it's about the water temperatures coming from/to the primary thermal grid
            return b.temperature_hex_in[t, n] - b.temperature_hex_out[t, n] == b.heat_flow[t]/n_segments/b.mass_flow[t] / self.cp
    self.block.decl_temperatures = Constraint(self.TIME, self.n_hex, rule=_decl_temperatures)
    ############# min supply temperature/ lower bound ###################
    uslack = self.make_slack('temperature_max_uslack', self.TIME)
    lslack = self.make_slack('temperature_max_l_slack', self.TIME)
    ub = self.params['temperature_max'].v()
    lb = self.params['temperature_min'].v()
    def _max_temp(b, t):
        return self.constrain_value(b.temperatures['supply', t],
                                    ub,
                                    ub=True,
                                    slack_variable=uslack[t])
    def _min_temp(b, t):
        return self.constrain_value(b.temperatures['supply', t],
                                    lb,
                                    ub=False,
                                    slack_variable=lslack[t])
    self.block.max_temp = Constraint(self.TIME, rule=_max_temp)
    self.block.min_temp = Constraint(self.TIME, rule=_min_temp)
    lslack = self.make_slack('temperature_l_slack', self.TIME)
    lb = self.params['temperature_min'].v()
else:
    raise Exception('It is not temperature driven!')
self.logger.info('Optimization model {} {} compiled'.
                 format(self.__class__, self.name))
self.compiled = True