Ejemplo n.º 1
0
    def solve(self,net):

        from optalg.opt_solver import OptSolverError
        from optalg.opt_solver import OptSolverIQP, OptSolverAugL, OptSolverIpopt
        
        # Parameters
        params = self._parameters
        solver_name = params['solver']
        solver_params = params['solver_parameters']

        # Solver
        if solver_name == 'iqp':
            solver = OptSolverIQP()
        elif solver_name == 'augl':
            solver = OptSolverAugL()
        elif solver_name == 'ipopt':
            solver = OptSolverIpopt()
        else:
            raise PFmethodError_BadOptSolver()
        solver.set_parameters(solver_params[solver_name])

        # Copy network
        net = net.get_copy()

        # Problem
        t0 = time.time()
        problem = self.create_problem(net)
        problem_time = time.time()-t0
                
        # Solve
        update = True
        t0 = time.time()
        try:
            solver.solve(problem)
        except OptSolverError as e:
            raise PFmethodError_SolverError(e)
        except Exception as e:
            update = False
            raise e
        finally:

            # Update network
            if update:
                net.set_var_values(solver.get_primal_variables()[:net.num_vars])
                net.update_properties()
                net.clear_sensitivities()
                problem.store_sensitivities(*solver.get_dual_variables())

            # Save results
            self.set_solver_name(solver_name)
            self.set_solver_status(solver.get_status())
            self.set_solver_message(solver.get_error_msg())
            self.set_solver_iterations(solver.get_iterations())
            self.set_solver_time(time.time()-t0)
            self.set_solver_primal_variables(solver.get_primal_variables())
            self.set_solver_dual_variables(solver.get_dual_variables())
            self.set_problem(None) # skip for now
            self.set_problem_time(problem_time)
            self.set_network_snapshot(net)
Ejemplo n.º 2
0
    def eval_Q(self,p,r,quiet=True,check=False,tol=1e-4,problem=None,return_data=False):
        """
        Evaluates Q(p,r) and its gradient.

        Parameters
        ----------
        p : generator powers
        r : renewable powers
        quiet : flag
        check : flag
        tol : evaluation tolerance 
        problem : QuadProblem
        return_data : flag

        Returns
        -------
        Q : value
        gQ : gradient
        """

        # Local vars
        num_p = self.num_p
        num_w = self.num_w
        num_r = self.num_r
        num_bus = self.num_bus
        num_br = self.num_br
        
        # Check
        assert(np.all(r > 0))
        
        # Problem
        if not problem:
            problem = self.get_problem_for_Q(p,r)
               
        try:

            # Solver
            solver = OptSolverIQP()
            solver.set_parameters({'quiet':quiet,
                                   'tol':tol})
            
            # Solve
            solver.solve(problem)

            # Info
            x = solver.get_primal_variables()
            lam,nu,mu,pi = solver.get_dual_variables()
            k = solver.get_iterations()
            q = x[:num_p]
            
            # Check
            if check:
                w = x[num_p:num_p+num_w]
                s = x[num_p+num_w:num_p+num_w+num_r]
                z = x[num_p+num_w+num_r:]
                assert(norm(self.G*(p+q)+self.R*s-self.A*w-self.b) < (1e-6)*norm(self.b))
                assert(norm(self.J*w-z) < (1e-6)*norm(z))
                assert(np.all(self.p_min <= p+q))
                assert(np.all(p+q <= self.p_max))
                assert(np.all(0 <= s))
                assert(np.all(s <= r))
                assert(np.all(self.z_min <= z))
                assert(np.all(self.z_max >= z))

            # Objective
            Q = 0.5*np.dot(q,self.H1*q)+np.dot(self.g1,q)
            
            # Gradient
            gQ = -(self.H1*q+self.g1)

            # Return
            if not return_data:
                return Q,gQ
            else:

                # Sensitivity (as linear operator)
                dqdpT = self.get_sol_sensitivity(problem,x,lam,mu,pi) # NEED TO GENERALIZE THIS TO dxdpT
                
                data = {'q': q,
                        'dqdpT': dqdpT}

                return Q,gQ,data

        # Errors
        except OptSolverError_MaxIters:
            return np.inf,None
        except OptSolverError_LineSearch:
            return np.inf,None
        except Exception,e:
            raise
Ejemplo n.º 3
0
u = np.array([0.8,0.8])
l = np.array([0.2,0.2])

problem = QuadProblem(H,g,A,b,l,u)

solver = OptSolverIQP()

solver.set_parameters({'quiet': True,
                       'tol': 1e-6})

solver.solve(problem)

print solver.get_status()

x = solver.get_primal_variables()
lam,nu,mu,pi = solver.get_dual_variables()

print x

print x[0] + x[1]

print l <= x

print x <= u

print pi

print mu

print np.linalg.norm(g+np.dot(H,x)-np.dot(A.T,lam)+mu-pi)
Ejemplo n.º 4
0
u = np.array([0.8, 0.8])
l = np.array([0.2, 0.2])

problem = QuadProblem(H, g, A, b, l, u)

solver = OptSolverIQP()

solver.set_parameters({'quiet': True, 'tol': 1e-6})

solver.solve(problem)

print solver.get_status()

x = solver.get_primal_variables()
lam, nu, mu, pi = solver.get_dual_variables()

print x

print x[0] + x[1]

print l <= x

print x <= u

print pi

print mu

print np.linalg.norm(g + np.dot(H, x) - np.dot(A.T, lam) + mu - pi)
Ejemplo n.º 5
0
    def solve(self,net,contingencies):
        """
        Solves preventive DCOPF problem.
        
        Parameters
        ----------
        net : Network
        contingencies : list of Contingencies
        """
        
        # Parameters
        params = self.parameters
        thermal_limits = params['thermal_limits']
        thermal_factor = params['thermal_factor']
        inf_flow = params['inf_flow']

        # Problem (base)
        problem = self.create_problem(net)
        
        # Projections
        Pw = net.get_var_projection(pfnet.OBJ_BUS,pfnet.BUS_VAR_VANG)
        Pp = net.get_var_projection(pfnet.OBJ_GEN,pfnet.GEN_VAR_P)
      
        # Construct QP
        x = problem.get_init_point()
        p = Pp*x
        w = Pw*x

        c_flows = problem.find_constraint(pfnet.CONSTR_TYPE_DC_FLOW_LIM)
        c_bounds = problem.find_constraint(pfnet.CONSTR_TYPE_LBOUND)
       
        problem.eval(x)

        phi = problem.phi
        
        Hp = Pp*(problem.Hphi + problem.Hphi.T - triu(problem.Hphi))*Pp.T
        gp = Pp*problem.gphi - Hp*p
        
        G = problem.A*Pp.T
        W = -problem.A*Pw.T
        b = problem.b.copy()
        
        lz = c_flows.l.copy()
        uz = c_flows.u.copy()
        J = c_flows.G*Pw.T

        # Flow limit expansion
        dz = (thermal_factor-1.)*(uz-lz)/2.
        if not thermal_limits:
            dz += inf_flow
        lz -= dz
        uz += dz

        lw = Pw*c_bounds.l
        uw = Pw*c_bounds.u
        Iw = Pw*c_bounds.G*Pw.T

        lp = Pp*c_bounds.l
        up = Pp*c_bounds.u
        Ip = Pp*c_bounds.G*Pp.T

        GWJ_list = [(G,W,J)]
        u_list = [up,uw,uz]
        l_list = [lp,lw,lz]
        b_list = [b,np.zeros(J.shape[0])]
        nz_list = [J.shape[0]]
        
        for cont in contingencies:

            # apply contingency
            cont.apply()

            problem.analyze()

            G = problem.A*Pp.T
            W = -problem.A*Pw.T
            b = problem.b.copy()
            
            lz = c_flows.l.copy()
            uz = c_flows.u.copy()
            J = c_flows.G*Pw.T

            # Flow limit expansion
            dz = (thermal_factor-1.)*(uz-lz)/2.
            if not thermal_limits:
                dz += inf_flow
            lz -= dz
            uz += dz
            
            GWJ_list.append((G,W,J))
            u_list += [uw,uz]
            l_list += [lw,lz]
            b_list += [b,np.zeros(J.shape[0])]
            nz_list.append(J.shape[0])

            # clear contingency
            cont.clear()
          
        problem.analyze()
  
        A = []
        num_blocks = len(GWJ_list)
        for i in range(num_blocks):

            G,W,J = GWJ_list[i]

            row1 = (2*num_blocks+1)*[None]
            row1[0] = G
            row1[2*i+1] = -W
            A.append(row1)

            row2 = (2*num_blocks+1)*[None]
            row2[2*i+1] = J
            row2[2*i+2] = -eye(J.shape[0],format='coo')
            A.append(row2)

        A = bmat(A,format='coo')
        b = np.hstack((b_list))
        l = np.hstack((l_list))
        u = np.hstack((u_list))

        n = A.shape[1]
        ng = Pp.shape[0]
        nw = Pw.shape[0]
        nz = nz_list[0]
        nr = n-ng
        m = A.shape[0]

        Zr = coo_matrix((nr,nr))
        zr = np.zeros(nr)
        
        H = bmat([[Hp,None],[None,Zr]],format='coo')/net.base_power # scaled
        g = np.hstack((gp,zr))/net.base_power                       # scaled

        y = np.hstack((p,zr))

        # Check limits
        if not np.all(l < u):
            raise PFmethodError_BadFlowLimits(self)
        
        # Other checks
        try:
            assert(ng+nw == net.num_vars)
            assert(b.shape == (m,))
            assert((Ip-eye(Pp.shape[0])).nnz == 0)
            assert((Iw-eye(Pw.shape[0])).nnz == 0)
            assert(l.shape == (n,))
            assert(u.shape == (n,))
            assert(np.abs(phi-net.base_power*(0.5*np.dot(y,H*y)+np.dot(g,y))) < 1e-8)
            assert(H.shape == (n,n))
            assert(m == num_blocks*net.num_buses+sum(nz_list))
            assert(np.linalg.norm(x-Pp.T*p-Pw.T*w,np.inf) < 1e-8)
        except AssertionError:
            raise PFmethodError_BadProblem(self)
                        
        QPproblem = QuadProblem(H,g,A,b,l,u)
        
        # Set up solver
        solver = OptSolverIQP()
        solver.set_parameters(params)
        
        # Solve
        try:
            solver.solve(QPproblem)
        except OptSolverError as e:
            raise PFmethodError_SolverError(self,e)
        finally:
            
            # Update net properties
            pwz = solver.get_primal_variables()
            x = Pp.T*pwz[:ng]+Pw.T*pwz[ng:ng+nw]
            z = pwz[ng+nw:ng+nw+nz]
            net.update_properties(x)

            # Prepare duals
            lam,nu,mu,pi = solver.get_dual_variables()
            lam = lam[:net.num_buses+nz]
            mu_p = mu[:ng]
            mu_w = mu[ng:ng+nw]
            mu_z = mu[ng+nw:ng+nw+nz]
            mu = np.hstack((Pp.T*mu_p+Pw.T*mu_w,mu_z))            
            pi_p = pi[:ng]
            pi_w = pi[ng:ng+nw]
            pi_z = pi[ng+nw:ng+nw+nz]
            pi = np.hstack((Pp.T*pi_p+Pw.T*pi_w,pi_z))
            
            # Get results
            self.set_status(solver.get_status())
            self.set_error_msg(solver.get_error_msg())
            self.set_iterations(solver.get_iterations())
            self.set_primal_variables(np.hstack((x,z)))
            self.set_dual_variables([lam,nu,mu,pi])
            self.set_net_properties(net.get_properties())
            self.set_problem(problem)
Ejemplo n.º 6
0
    def solve(self,net):
        
        # Parameters
        params = self.parameters
        thermal_limits = params['thermal_limits']
        thermal_factor = params['thermal_factor']
        inf_flow = params['inf_flow']

        # Check parameters
        if thermal_factor < 0.:
            raise PFmethodError_BadParam(self,'thermal_factor')

        # Problem
        problem = self.create_problem(net)

        # Renewables
        Pr = net.get_var_projection(pfnet.OBJ_VARGEN,pfnet.VARGEN_VAR_P)
       
        # Construct QP
        x = problem.get_init_point()
        problem.eval(x)
        c_flows = problem.find_constraint(pfnet.CONSTR_TYPE_DC_FLOW_LIM)
        c_bounds = problem.find_constraint(pfnet.CONSTR_TYPE_LBOUND)
        
        Hx = problem.Hphi + problem.Hphi.T - triu(problem.Hphi)
        gx = problem.gphi - Hx*x
        
        Ax = problem.A
        bx = problem.b
        
        lz = c_flows.l
        uz = c_flows.u
        Gz = c_flows.G

        # Flow limit expansion
        dz = (thermal_factor-1.)*(uz-lz)/2.
        if not thermal_limits:
            dz += inf_flow
        lz -= dz
        uz += dz
  
        lx = c_bounds.l
        ux = c_bounds.u
        Gx = c_bounds.G
        
        ux += Pr.T*Pr*(x-ux) # correct limit for curtailment

        nx = net.num_vars
        nz = net.get_num_branches_not_on_outage()*net.num_periods
        n = nx+nz

        Iz = eye(nz)
        Oz = coo_matrix((nz,nz))
        oz = np.zeros(nz)
        
        H = bmat([[Hx,None],[None,Oz]],format='coo')
        g = np.hstack((gx,oz))

        A = bmat([[Ax,None],[Gz,-Iz]],format='coo')
        b = np.hstack((bx,oz))

        l = np.hstack((lx,lz))
        u = np.hstack((ux,uz))

        y = np.hstack((x,oz))

        # Check flow limits
        if not np.all(lz < uz):
            raise PFmethodError_BadFlowLimits(self)
        
        # Check variable limits
        if not np.all(lx < ux):
            raise PFmethodError_BadVarLimits(self)

        # Other checks
        try:
            assert(Gx.shape == (nx,nx))
            assert(np.all(Gx.row == Gx.col))
            assert(np.all(Gx.data == np.ones(nx)))
            assert(Gz.shape == (net.get_num_branches_not_on_outage()*net.num_periods,nx))
            assert(l.shape == (n,))
            assert(u.shape == (n,))
            assert(np.all(l < u))
            assert(norm(np.hstack((problem.gphi,oz))-(H*y+g)) < 1e-10*(1.+norm(problem.gphi)))
            assert(H.shape == (n,n))
            assert(A.shape == (net.num_buses*net.num_periods+nz,n))
        except AssertionError:
            raise PFmethodError_BadProblem(self)
            
        QPproblem = QuadProblem(H,g,A,b,l,u)
        
        # Set up solver
        solver = OptSolverIQP()
        solver.set_parameters(params)
        
        # Solve
        try:
            solver.solve(QPproblem)
        except OptSolverError as e:
            raise PFmethodError_SolverError(self,e)
        finally:

            # Update net properties
            net.update_properties(solver.get_primal_variables()[:net.num_vars])
            
            # Get results
            self.set_status(solver.get_status())
            self.set_error_msg(solver.get_error_msg())
            self.set_iterations(solver.get_iterations())
            self.set_primal_variables(solver.get_primal_variables())
            self.set_dual_variables(solver.get_dual_variables())
            self.set_net_properties(net.get_properties())
            self.set_problem(problem)