двухиндексированная переменная в Pyomo, с использованием для объявления переменной во времени и разделе / ​​блоке - PullRequest
0 голосов
/ 02 августа 2020

Я пытаюсь смоделировать теплообменник с n сегментами в pyomo, но получаю странные результаты. если я просто использую переменную, зависящую от времени (без индекса сегмента для переменной), получится правильный результат. Однако, рассматривая сегменты как еще один индекс для переменной T, я сталкиваюсь с проблемой (нереалистичность c колебания).

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)

для n_segments = 1 в этом коде, я ожидаю получить тот же результат, что и когда переменная просто зависит от времени (без индекса n_segments). Итак, есть ли проблемы с индексированием, которое я использую?

...