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
def solve_approx(self,g_corr=None,tol=1e-4,quiet=False,samples=500,init_data=None): """ Solves certainty equivalent problem with slope correction. Parameters ---------- g_corr : slope correction tol : optimality tolerance quiet : flag samples : number of samples Returns ------- p : generator powers """ # Constants 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 Ow = coo_matrix((num_w,num_w)) Os = coo_matrix((num_r,num_r)) Oz = coo_matrix((num_br,num_br)) Onp = coo_matrix((num_bus,num_p)) Onz = coo_matrix((num_bus,num_br)) ow = np.zeros(num_w) os = np.zeros(num_r) oz = np.zeros(num_br) Iz = eye(num_br,format='coo') # Slope correction if g_corr is None: g_corr = np.zeros(num_p) # Problem construction H = bmat([[self.H0+self.H1,-self.H1,None,None,None], # p [-self.H1,self.H1,None,None,None], # y = p + q [None,None,Ow,None,None], # w [None,None,None,Os,None], # s [None,None,None,None,Oz]], # z format='coo') g = np.hstack((self.g0-self.g1+g_corr,self.g1,ow,os,oz)) A = bmat([[Onp,self.G,-self.A,self.R,Onz], [None,None,self.J,None,-Iz]],format='coo') b = np.hstack((self.b,oz)) l = np.hstack((self.p_min, # p self.p_min, # y self.w_min, # w os, # s self.z_min)) # z u = np.hstack((self.p_max, self.p_max, self.w_max, self.Er, self.z_max)) # Problem if init_data is None: problem = QuadProblem(H,g,A,b,l,u) else: problem = QuadProblem(H,g,A,b,l,u, x=init_data['x'], lam=init_data['lam'], mu=init_data['mu'], pi=init_data['pi']) # Solve solver = OptSolverIQP() solver.set_parameters({'quiet':quiet, 'tol':tol}) solver.solve(problem) results = solver.get_results() x = results['x'] lam = results['lam'] mu = results['mu'] pi = results['pi'] # Check problem.eval(x) gphi = problem.gphi assert(norm(gphi-A.T*lam+mu-pi) < (1e-6)*(norm(gphi)+norm(lam)+norm(mu)+norm(pi))) assert(norm(mu*(u-x)) < (1e-6)*(norm(mu)+norm(u-x))) assert(norm(pi*(x-l)) < (1e-6)*(norm(pi)+norm(x-l))) assert(np.all(x < u)) assert(np.all(x > l)) assert(norm(A*x-b) < (1e-6)*norm(b)) # Return return x[:num_p],results
def solve(self,net): # Parameters params = self.parameters num_sce = params['scenarios'] maxiters = params['maxiters'] samples = params['samples'] t_max = params['t_max'] z_max = params['z_max'] # Problem problem = self.create_problem(net) # Initial point p = problem.solve_certainty_equivalent() # Scenarios scenarios = [problem.sample_w() for i in range(num_sce)] # Matvecs H0 = problem.H0 g0 = problem.g0 p_min = problem.p_min p_max = problem.p_max A1 = np.zeros((0,p.size+1)) b = np.zeros(0) # Init eval Q,gQ = map(lambda l: sum(l)/float(num_sce),zip(*map(lambda r: problem.eval_Q(p,r),scenarios))) # Iteartions t = 0 num_z = 0 t0 = time.time() solved = False for k in range(maxiters): # Show info t1 = time.time() F = 0.5*np.dot(p,H0*p)+np.dot(g0,p) + Q EF,EgF = problem.eval_EF(p,samples=samples) print '%d,%.2f,%.2e,%.2e,%.5e,%.5e' %(k,t1-t0,Q,t,F,EF) t0 += time.time()-t1 # Solved if solved: print 'solved' break # Add cut a = np.hstack((-gQ,1.)) A1 = np.vstack((A1,a)) b = np.hstack((b,Q-np.dot(gQ,p))) num_z += 1 # Prepare problem A1sp = coo_matrix(A1) A = bmat([[A1sp,-eye(num_z)]],format='coo') H = bmat([[H0,None,None], [None,coo_matrix((1,1)),None], [None,None,coo_matrix((num_z,num_z))]],format='coo') g = np.hstack((g0,1,np.zeros(num_z))) u = np.hstack((p_max,t_max,z_max*np.ones(num_z))) l = np.hstack((p_min,-t_max,np.zeros(num_z))) qp_prob = QuadProblem(H,g,A,b,l,u) # Solve problem qp_sol = OptSolverIQP() qp_sol.set_parameters({'quiet':True}) qp_sol.solve(qp_prob) # Get results x = qp_sol.get_primal_variables() p = x[:p.size] t = x[p.size] z = x[p.size+1:] assert(np.all(z > 0)) # Eval Q,gQ = map(lambda l: sum(l)/float(num_sce),zip(*map(lambda r: problem.eval_Q(p,r),scenarios))) # Check solved if Q <= t: solved = True
def solve(self,net): # Parameters params = self.parameters # Problem problem = self.create_problem(net) # 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 lx = c_bounds.l ux = c_bounds.u Gx = c_bounds.G nx = net.num_vars nz = net.num_branches n = nx+nz Iz = eye(nz) Oz = coo_matrix((nz,nz)) oz = np.zeros(nz) H = bmat([[Hx,None],[None,Oz]],format='coo')/net.base_power g = np.hstack((gx,oz))/net.base_power 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.num_branches,nx)) assert(l.shape == (n,)) assert(u.shape == (n,)) assert(np.all(l < u)) assert(np.linalg.norm(problem.l-l,np.inf) < 1e-10) assert(np.linalg.norm(problem.u-u,np.inf) < 1e-10) assert(np.abs(problem.phi-net.base_power*(0.5*np.dot(y,H*y)+np.dot(g,y))) < 1e-8) assert(H.shape == (n,n)) assert(A.shape == (net.num_buses+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,e: raise PFmethodError_SolverError(self,e)
import numpy as np from optalg.opt_solver import OptSolverIQP, QuadProblem g = np.array([3., -6.]) H = np.array([[10., -2], [-2., 10]]) A = np.array([[1., 1.]]) b = np.array([1.]) 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
import numpy as np from optalg.opt_solver import OptSolverIQP, QuadProblem g = np.array([3.,-6.]) H = np.array([[10.,-2], [-2.,10]]) A = np.array([[1.,1.]]) b = np.array([1.]) 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]
def solve(self,net): # Parameters params = self.parameters num_sce = params['scenarios'] maxiters = params['maxiters'] maxtime = params['maxtime'] period = params['period'] z_inf = params['z_inf'] y_inf = params['y_inf'] quiet = params['quiet'] gamma = params['gamma'] # Problem problemRA = self.create_problem(net,params) problem = problemRA.ts_dcopf self.problem = problemRA # Scenarios scenarios = [problem.sample_w() for i in range(num_sce)] # Constants num_p = problem.num_p H0 = problem.H0 g0 = problem.g0 p_min = problem.p_min p_max = problem.p_max t_min = params['t_min']*problemRA.Qref t_max = params['t_max']*problemRA.Qref op = np.zeros(num_p) # For base eq A0 = bmat([[op,1.-gamma,0,1.,-1.]]) # p t z1 z2 z3 b0 = np.zeros(1) # For obj cuts eq A1 = np.zeros((0,num_p+4)) b1 = np.zeros(0) # For constr cuts eq A2 = np.zeros((0,num_p+4)) b2 = np.zeros(0) # Header if not quiet: print('\nSAA Cutting-Plane Risk') print('-----------------------') print('{0:^8s}'.format('iter'), end=' ') print('{0:^10s}'.format('time(s)'), end=' ') print('{0:^12s}'.format('FL'), end= ' ') print('{0:^12s}'.format('GL'), end= ' ') print('{0:^12s}'.format('saved')) # Init k = 0 t1 = 0 num_y = 0 t0 = time.time() self.results = [] # Loop while True: # Construct master H = bmat([[H0,coo_matrix((num_p,4+2*num_y))], [coo_matrix((4+2*num_y,num_p)),None]],format='coo') g = np.hstack((g0,0.,1.,np.zeros(2+2*num_y))) if num_y > 0: A = bmat([[A0,None,None], [A1,-eye(num_y),None], [A2,None,-eye(num_y)]],format='coo') else: A = bmat([[A0]],format='coo') b = np.hstack((b0,b1,b2)) l = np.hstack((p_min, # p t_min, # t -z_inf, # z1 -z_inf, # z2 -z_inf, # z3 -y_inf*np.ones(num_y), # y1 -y_inf*np.ones(num_y))) # y2 u = np.hstack((p_max, # p t_max, # t z_inf, # z1 z_inf, # z2 0, # z3 np.zeros(num_y), # y1 np.zeros(num_y))) # y2 qp = QuadProblem(H,g,A,b,l,u) # Solve problem solver = OptSolverIQP() solver.set_parameters({'quiet': True, 'tol': self.parameters['tol']}) solver.solve(qp) assert(solver.get_status() == 'solved') x_full = solver.get_primal_variables() p = x_full[:num_p] t = x_full[num_p] z1 = x_full[num_p+1] z2 = x_full[num_p+2] self.x = x_full[:num_p+1] # Save if time.time()-t0 > t1: self.results.append((k,time.time()-t0,self.x,np.nan)) t1 += period # Iters if k >= maxiters: break # Maxtime if time.time()-t0 >= maxtime: break # Obj saa Q_list,gQ_list = zip(*[problem.eval_Q(p,w) for w in scenarios]) Q = sum(Q_list)/float(num_sce) gQ = sum(gQ_list)/float(num_sce) # Constr saa S_list = [] gS_list = [] for i in range(num_sce): qq = Q_list[i]-problemRA.Qmax-t S_list.append(np.maximum(qq,0.)) if qq >= 0.: gS_list.append(np.hstack((gQ_list[i],-1.))) else: gS_list.append(np.hstack((op,0.))) S = sum(S_list)/float(num_sce) gS = sum(gS_list)/float(num_sce) # Obj cut a1 = np.hstack((gQ,0.,-1.,0.,0.)) A1 = np.vstack((A1,a1)) b1 = np.hstack((b1,-Q+np.dot(gQ,p))) # Constraint cut a2 = np.hstack((gS,0.,-1.,0.)) A2 = np.vstack((A2,a2)) b2 = np.hstack((b2,-S+np.dot(gS,self.x))) # Output if not quiet: print('{0:^8d}'.format(k), end=' ') print('{0:^10.2f}'.format(time.time()-t0), end=' ') print('{0:^12.5e}'.format(0.5*np.dot(p,H0*p)+np.dot(g0,p)+z1), end=' ') print('{0:^12.5e}'.format((1.-gamma)*t+z2), end=' ') print('{0:^12d}'.format(len(self.results))) # Update num_y += 1 k += 1
def solve(self,net): # Parameters params = self.parameters num_sce = params['scenarios'] maxiters = params['maxiters'] samples = params['samples'] t_max = params['t_max'] z_max = params['z_max'] # Problem problem = self.create_problem(net) # Initial point p,results = problem.solve_approx(quiet=True) # Scenarios scenarios = [problem.sample_w() for i in range(num_sce)] # Matvecs H0 = problem.H0 g0 = problem.g0 p_min = problem.p_min p_max = problem.p_max A1 = np.zeros((0,p.size+num_sce)) b = np.zeros(0) # Init eval Qlist,gQlist = list(zip(*[problem.eval_Q(p,r) for r in scenarios])) # Iteartions t = np.zeros(num_sce) num_z = 0 counter = 0 t0 = time.time() solved = False for k in range(maxiters): # Show info t1 = time.time() Q = sum(Qlist)/float(num_sce) F = 0.5*np.dot(p,H0*p)+np.dot(g0,p) + Q EF,EgF = problem.eval_EF(p,samples=samples) print(('%d,%.2f,%d,%.2e,%.2e,%.5e,%.5e' %(k,t1-t0,counter,Q,np.sum(t)/float(num_sce),F,EF))) t0 += time.time()-t1 # Solved if solved: print('solved') break # Add cuts counter = 0 a = np.zeros((0,p.size+num_sce)) for i in range(num_sce): if (k == 0 or Qlist[i] > t[i]): ei = np.zeros(num_sce) ei[i] = 1. a = np.vstack((a,np.hstack((-gQlist[i],ei)))) b = np.hstack((b,Qlist[i]-np.dot(gQlist[i],p))) counter += 1 num_z += counter A1 = np.vstack((A1,a)) # Prepare problem A1sp = coo_matrix(A1) A = bmat([[A1sp,-eye(num_z)]],format='coo') H = bmat([[H0,None,None], [None,coo_matrix((num_sce,num_sce)),None], [None,None,coo_matrix((num_z,num_z))]],format='coo') g = np.hstack((g0,np.ones(num_sce)/float(num_sce),np.zeros(num_z))) u = np.hstack((p_max,t_max*np.ones(num_sce),z_max*np.ones(num_z))) l = np.hstack((p_min,-t_max*np.ones(num_sce),np.zeros(num_z))) qp_prob = QuadProblem(H,g,A,b,l,u) # Solve problem qp_sol = OptSolverIQP() qp_sol.set_parameters({'quiet':True}) qp_sol.solve(qp_prob) # Get results x = qp_sol.get_primal_variables() p = x[:p.size] t = x[p.size:p.size+num_sce] z = x[p.size+num_sce:] assert(np.all(z > 0)) # Eval Qlist,gQlist = list(zip(*[problem.eval_Q(p,r) for r in scenarios])) # Check solved if all([Qlist[i] <= t[i] for i in range(num_sce)]): solved = True
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 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)