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)
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
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)
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)
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)
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)