Wednesday, 13 July 2022

In CVXPY, how would you make a boolean variable to check if something has changed?

I have an issue when using CVXPY that I wish to calculate the input flow for a calculation for an additional constraint within my program, I have a selection boolean variable that I am using to determine the flow rate which in turn is used to reshape a vector to fit what I need.

In this sense I am calculating estimated reservoir flows over a 24 hour period, so the selected flows are set across 7 periods of varying time periods (split into 30 minute intervals), the problem I am trying to sort is that often, it could take maybe 4 30 minute periods to go from say 15 l/s to the desired 17 l/s flow rate which can ultimate have a large effect on my calculation for smaller surface areas which is what I wish to eliminate here.

Example output currently for 1 period out of 7 (00:00 - 08:00):
[120 120 120 120 120 120 120 120 120 120 120 120 120 120 120 120]

# Imagine our ramp rate is actually 0.5l/s per 30 minutes and currently at 118l/s
Expected output:
[118 118.5 119 119.5 120 120 120 120 120 120 120 120 120 120 120 120]

I hope above example makes sense to what I wish to achieve

See below my current solution that I have implemented without a ramp rate developed in to the current problem.

        FACTOR = 1/self.SURFACE_AREA
        input_flow_matrix=np.zeros((max(period_lengths),len(period_lengths)))
        for i,l in enumerate(period_lengths):
            input_flow_matrix[:l,i]=1
        selection = cp.Variable(shape=cost_.shape,boolean=True)
        assignment_constraint = cp.sum(selection,axis=1) == 1
        input_flow_= cp.sum(cp.multiply(flow_,selection),axis=1)
        input_flow_vector=cp.vec(cp.multiply(input_flow_matrix,np.ones((max(period_lengths), 1)) @ cp.reshape(input_flow_,(1,len(period_lengths)))))

        res_flow= (input_flow_vector-cp.vec(out_flow_))
        net_volume = res_flow * 1.8
        res_level=cp.cumsum(net_volume) * FACTOR + initial_level
        volume_= cp.sum(cp.multiply(volume_,selection))
        volume_constraint = volume_ >= v_min
        min_level_constraint = res_level >= min_level
        max_level_constraint = res_level <= max_level

        constraints = [assignment_constraint, max_level_constraint, min_level_constraint, volume_constraint]

        cost_ = cp.sum(cp.multiply(cost_,selection))
        assign_prob = cp.Problem(cp.Minimize(cost_),constraints)
        assign_prob.solve(solver=cp.CPLEX, verbose=False)

My assumption here would be to include a boolean variable that would indicate if the flow rate is changing across my 7 periods which is from the input_flow_ variable. However I am just unsure how to actually develop a good solution, would this be needed over a matrix or something similar? Any help would be much appreciated.

I can provide figures if it helps with reproducibility.



from In CVXPY, how would you make a boolean variable to check if something has changed?

No comments:

Post a Comment