Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Modelo de Flujo Optimo de Potencia Utilizando Tecnicas de Optimizacion PDF
Modelo de Flujo Optimo de Potencia Utilizando Tecnicas de Optimizacion PDF
INGENIERO ELECTRICISTA
POR:
JULIO CÉSAR FERNÁNDEZ GONZÁLEZ
EVER ESMITH FUENTES LÓPEZ
OCTUBRE 2011
ANTIGUO CUSCATLÁN, EL SALVADOR, C.A.
RECTOR
SECRETARIA GENERAL
CELINA PÉREZ RIVERA
LECTOR
DAVID ADONAY MURCIA ANDRADE
RESUMEN EJECUTIVO
Hoy en día, la electricidad es, sin lugar a dudas, el principal motor que impulsa las actividades en
cualquier país y permite su desarrollo.
Todos los sistemas de potencia deben estar diseñados para adaptarse a sus usuarios respetando
varios criterios de calidad en el servicio. Estos criterios se refieren a los valores mínimo y máximo
de la tensión en los puntos de entrega, la frecuencia de máxima excursión en el valor nominal, etc.
El problema de flujo de potencia es calcular la magnitud del voltaje y el ángulo de fase en cada bus
de un sistema de potencia en condiciones de estado estable trifásico. Como subproducto de este
cálculo, se pueden calcular flujos de potencia real y reactiva en equipo como líneas de transmisión
y transformadores, así como pérdidas de equipo.
El punto de partida para un problema de flujo de potencia es un diagrama unifilar del sistema de
potencia, a partir del cual se pueden obtener los datos de entrada para las soluciones por
computadora.
Es de tener en cuenta que no solo importa la solución de flujos de potencia para la satisfacción de
la demanda, también es muy importante el aspecto económico, por lo cual en este trabajo de
graduación también se enfatizara en la resolución de flujos de potencia óptimo. Su principal
objetivo es optimizar las condiciones de operación en estado estacionario de un sistema eléctrico
de potencia. Un OPF ajusta las cantidades controlables para optimizar una función objetivo
mientras satisface un conjunto de restricciones operativas.
i
ii
ÍNDICE
iii
4.3.1 OPF de un sistema de dos nodos y modelado AC: sin restricciones de desigualdad. Por
método de Newton-Raphson ..................................................................................................... 41
4.3.2 OPF de un sistema multimodal y modelado DC: sin restricciones de desigualdad. Por
método de Newton-Raphson ..................................................................................................... 47
BIBLIOGRAFIA .................................................................................................................................. 57
ANEXOS
ANEXO A. PROGRAMA DE FLUJOS DE POTENCIA
ANEXO B. PROGRAMA DE FLUJO OPTIMO DEPOTENCIA (OPF) MODELO AC
ANEXO C. PROGRAMA DE FLUJO OPTIMO DE POTENCIA (OPF) MODELO DC
iv
INDICE DE FIGURAS
v
vi
PRÓLOGO
El objetivo principal de este trabajo es el diseñar un programa que sea capaz de solucionar el
problema de flujo de carga para cualquier sistema eléctrico de potencia que se desee analizar. Así
como implementar un programa capaz de resolver problemas de flujo óptimo de potencia. En base
a esto se tiene que tener en cuenta que:
A lo largo del capitulo 3 se elabora el programa para la solución del flujo de potencia, así como los
módulos que conforman este programa detallando cada uno de estos. También se presenta un
problema sencillo de un sistema de 3 nodos al cual se le aplica el programa elaborado para la
solución de este. Además se resuelve un sistema de potencia compuesto por 14 nodos
presentando sus resultados y comparándolos con otro programa.
En el capitulo 4 y ultimo, se define lo que es un flujo optimo de potencia, así como el problema de
flujo optimo de potencia. Se presenta su formulación general, variables y sus restricciones, por
último se resuelve 2 sistemas de potencia, uno modelando AC y el otro modelado DC el cual se
procederá a realizar un programa de forma general para el modelo DC.
vii
viii
CAPITULO 1. MODELADO DE LOS ELEMENTOS DEL SISTEMA DE POTENCIA
Se detallaran los diferentes elementos del sistema de potencia que se tomaran en cuenta para el
análisis del flujo de potencia, por lo cual se explicaran los distintos modelos de cada uno de estos
elementos.
Las líneas de transmisión pueden clasificarse en: cortas medianas y largas, y en base a eso se
obtiene un modelo matemático que debe ser tomado en cuenta al momento de la simulación de
flujos de potencia.
Líneas Cortas: El circuito de la figura 1.1 representa una línea de transmisión corta, por lo
común aplicadas a líneas con menos de 80 km de largo y a 60 Hz. Además para este caso
la admitancia en derivación se desprecia.
Líneas Medianas: Para las líneas de longitud media, que por lo general varían de 80 a
250 km, a 60 Hz, es frecuente concentrar la capacitancia total en derivación y situar la
mitad en cada extremo de la línea. En la figura 1.2 se muestra el circuito equivalente para
este tipo de línea.
Líneas Largas: Las líneas a 60 Hz, con una longitud mayor a 240 km, son consideradas
como largas. Para este tipo de línea debe considerarse el hecho de que los parámetros de
la línea no están agrupados sino distribuidos uniformemente a lo largo de la línea. El
circuito de la figura 1.3 muestra una sección de línea.
1
Figura 1.3 Modelo línea larga
CIRCUITO NOMINAL
Ec.1.2
Ec.1.3
Donde: Ec.1.4
Ec .1.5
2
Ec.1.6
Sustituyendo en se tiene:
Ec.1.7
Donde: Ec.1.8
Ec.1.9
Ec.1.10
Ec.1.11
3
CIRCUITO EQUIVALENTE
El circuito que se muestra en la figura 1.5 se llama circuito equivalente. Es idéntico en estructura
al circuito nominal excepto en que se usan y en lugar de Z y Y. El objetivo es determinar y
´ tales que el circuito equivalente tenga los mismos parámetros ABCD que los de la línea
distribuida. Los parámetros ABCD del circuito equivalente, el cual tiene la misma estructura que
el circuito nominal, son:
Ec.1.12
Ec.1.13
Ec.1.14
Ec.1.15
Ec.1.16
Ec.1.17
Ec.1.18
En donde
4
Ec.1.20
Ec.1.21
Ec.1.22
En donde
Las ecuaciones (1.1.19) y (1.1.23) dan los factores de corrección y para convertir Z y Y, para
el circuito nominal, en Z´ y Y´ para el circuito equivalente.
En el caso de estudio se utiliza un modelo PI equivalente para la línea, el cual, a través de sus
elementos, representa los efectos físicos producidos en la línea de transmisión.
Con este modelo se establece la relación entre las corrientes y tensiones a través de la matriz
compleja de admitancias. Las magnitudes de los elementos del modelo PI, son utilizados por el
OPF (Flujo Optimo de Potencia) para calcular la matriz de admitancia nodal compleja del sistema
completo. Ésta participa directamente en las ecuaciones de flujo de potencia y determina las
pérdidas en las líneas de transmisión.
Los transformadores, son elementos que tienen la capacidad de transformar tensiones alternas.
Además, pueden cambiar su razón de transformación a través de los denominados taps, que
dependiendo del tipo de transformador, pueden ser manipulados de distintas formas por los
operadores de la red.
5
Al igual que en el caso de las líneas de transmisión, se establece la relación entre las corrientes y
tensiones través de la matriz de admitancias.
En la figura 1.6 (b) se muestra el circuito equivalente por unidad de este transformador ideal para la
operación trifásica balanceada.
Por convención, se adoptaran las dos reglas siguientes para seleccionar las cantidades bases:
para que sea igual a la relación de las tensiones nominales línea a línea,
6
1.2.2 Transformadores de tres devanados
En la figura 1.7 (a) se muestra un transformador monofásico básico de tres devanados. Se puede
extender con facilidad las relaciones del transformador ideal de dos devanados, con el fin de
obtener las relaciones correspondientes para un transformador ideal de tres devanados. En
unidades reales, estas relaciones son:
Ec.1.24
Ec.1.25
En donde entra por la terminal con punto, e salen por las terminales con punto, y , y
tienen sus polaridades en las terminales con punto. Por unidad las ecuaciones quedan así:
Ec.1.26
Ec.1.27
En donde se selecciona una para los tres devanados, y las bases de tensión se seleccionan
en proporción a las tensiones nominales de los devanados. El circuito equivalente por unidad
mostrado en la figura 1.7 (b) satisface estas dos relaciones por unidad. En el circuito del
transformador practico de tres devanados que se muestra en la figura 1.7 (c), también se incluye la
impedancia externa en serie y las ramas de admitancia en derivación.
7
= impedancia de dispersión por unidad medida del devanado 1, con el devanado 2 en
cortocircuito y el 3 abierto.
= impedancia de dispersión por unidad medida del devanado 1, con el devanado 3 en
cortocircuito y el 2 abierto.
= impedancia de dispersión por unidad medida del devanado 2, con el devanado 3 en
cortocircuito y el 1 abierto.
Se puede usar las ecuaciones antes mencionadas para evaluar las impedancias en serie por
unidad, , y , del circuito equivalente del transformador de tres devanados, a partir de las
impedancias de dispersión por unidad , y , las cuales, a su vez, se determinan a partir de
pruebas de cortocircuito.
Note que cada uno de los devanados en un transformador de tres de ellos puede tener una
capacidad nominal diferente en KVA. Si las impedancias de dispersión de las pruebas de
cortocircuito se expresan por unidad, con base en las capacidades nominales de los devanados,
primero deben convertirse por unidad respecto a una común, antes de que se usen en las
ecuaciones.
8
CAPITULO 2. FLUJOS DE POTENCIA
2.1 Introduccion
Con los antecedentes del capitulo anterior, ya se tienen las bases para estudiar las características
de operación de un sistema eléctrico de potencia. El régimen permanente simétrico es, de hecho,
el modo más importante de operación de un sistema eléctrico de potencia. Enseguida se
relacionan, en orden jerárquico, tres importantes problemas que se encuentra en este modo de
operación:
Este capitulo se dedica al problema de flujo de carga. El estudio de flujo de carga, en la jerga de
sistemas eléctricos de potencia, es la solución de régimen permanente de la red del sistema. La
principal información que se obtiene de este estudio incluye las magnitudes y los ángulos de fase
de voltajes de buses, potencia reactiva en los buses del generador, flujo real y reactivo de
potencias en las líneas de transmisión y otras variables que se especifiquen. Esta información es
esencial para el monitoreo continuo del estado actual del sistema y para analizar la eficacia de
plantas alternas para futuras expansiones del sistema para satisfacer una demanda creciente de
carga.
La red contiene cientos de nodos y ramas con una impedancia especificada en por unidad sobre
una base imponible común MVA.
Las ecuaciones de red pueden ser formuladas de forma sistemática en una variedad de formas.
Sin embargo, el método de voltaje de nodos, que es la forma más adecuada para muchos análisis
del sistema de potencia, es comúnmente usado. La formulación de las ecuaciones de red en la
admitancia nodal forma resultados de ecuaciones algebraicas lineales simultáneas complejas en
términos de corrientes de nodo. Cuando las corrientes de nodo se especifican, el conjunto de
ecuaciones lineales pueden ser resueltas por los voltajes de nodo. Sin embargo, en un sistema de
potencia, las potencias son conocidas y no las corrientes. Por lo tanto, las ecuaciones resultantes
en términos de potencia, son conocidas como las ecuaciones de flujo de potencia, se convierten en
ecuaciones no lineales y deben ser resueltas por técnicas iterativas. . Los estudios de flujo de
potencia, comúnmente conocido como flujo de carga, son necesarios para el funcionamiento, la
programación económica y el intercambio de energía entre empresas de servicios públicos.
Además, el análisis de flujo de potencia se requiere para muchos otros análisis, tales como la
estabilidad transitoria y los estudios de contingencia.
9
2.2 Metodo de Newton-Raphson
Antes de explicar como se aplica el método NR para resolver el problema de flujo de carga, es útil
revisar el método en su forma general.
; Ec.2.1
Suponga que los valores iniciales de las incógnitas son Sean las
correcciones que, al hacerse a la primera suposición, dan la solución real. Por lo tanto,
Ec.2.2
Ec.2.3
se conoce como matriz jacobiana (que se obtiene al diferenciar el vector función con
respecto a y se evalúa en ). La ecuación anterior se puede escribir como:
Ec.2.5
10
Se puede obtener valores aproximados de corrección . Como estos constituyen un sistema de
ecuaciones algebraicas lineales se pueden resolver de manera eficiente mediante triangulación y
resustitucion.
Ec.2.6
Las iteraciones se continúan hasta que la ecuación (2.1) se satisfaga para cualquier exactitud
deseada, es decir,
(un valor especificado); Ec.2.7
REPRESENTACION GRAFICA
Este método, el cual es un método iterativo, es uno de los más usados y efectivos. El método de
Newton-Raphson no trabaja sobre un intervalo sino que basa su fórmula en un proceso iterativo.
Evaluando un valor cercano a la raíz en la función y trazando una recta tangente en el punto
se obtiene un nuevo valor que es mucho más cercano a la raíz que
Ec.2.8
11
Se supone que sea igual a 0 para que sea una raíz de
Ec.2.9
Pero en el punto , la pendiente m puede tomarse como por ser la mejor aproximación
a la pendiente en dicho punto.
Ec.2.10
Ec.2.11
Y despejamos
Ec.2.10
Ec.2.11
Si nuevamente se busca otra aproximación que es cada vez más cercana a la raíz,
Ec.2.12
Ec.2.13
Note que el método de Newton-Raphson no trabaja con intervalos donde nos asegure que
encontraremos la raíz, y de hecho no tenemos ninguna garantía de que nos aproximaremos a
dicha raíz. Desde luego, existen ejemplos donde este método no converge a la raíz, en cuyo caso
se dice que el método diverge. Sin embargo, en los casos donde si converge a la raíz lo hace con
una rapidez impresionante, por lo cual es uno de los métodos preferidos por excelencia.
12
2.3 El problema de flujo de potencia
El problema de flujo de potencia es calcular la magnitud del voltaje y el ángulo de fase en cada bus
de un sistema de potencia en condiciones de estado estable trifásico.
Como subproducto de este cálculo, se pueden calcular flujos de potencia rea y reactiva en equipo
como líneas de transmisión y transformadores, así como pérdidas de equipo.
El punto de partida para un problema de flujo de potencia es un diagrama unifilar del sistema de
potencia, a partir del cual se pueden obtener los datos de entrada para soluciones por
computadora. Los datos de entrada consisten en datos de buses, datos de las líneas de
transmisión y de los transformadores.
Como se muestra en la figura 2.2, las cuatro variables siguientes están asociadas con cada bus k:
magnitud de voltaje , ángulo de fase , potencia neta real y potencia activa abastecida al
bus.
Bus k
G Carga
L
En cada bus, dos de las variables se especifican como datos de entrada y las otras dos son
incógnitas que se calcularan mediante el programa de flujo de potencia. Por conveniencia, la
potencia entregada al bus en la figura 2.2 se separa en generación y carga. Es decir,
Bus compensador: Solo hay un bus compensador, que por conveniencia en este trabajo se
le asigna el numero 1. El bus compensador es una referencia para la cual , por lo
13
común 1.0 por unidad, es un dato de entrada. El programa de flujo de potencia calcula
y .
Sus instrucciones, por así decirlo, es hacer lo que sea necesario para mantener el
equilibrio de potencia real en el sistema, esto significa mantener el ángulo de tensión
constante.
Bus de carga: y son datos de entrada. El programa de flujo de potencia calcula y
. La mayor parte de los buses en un programa normal de flujo de potencia son de carga.
Bus de voltaje controlado: y son datos de entrada. El programa de flujo de potencia
calcula y . Como ejemplos están los buses a los que están conectados los
generadores, capacitores en derivación desconectables, o sistemas compensadores
estáticos de VARs. Los límites de VARs máximo y mínimo y que este tipo
puede suministrar son también datos de entrada. Otro ejemplo es un bus al que esta
conectado un transformador con cambiador de derivaciones; el programa de flujo de
potencia calcula entonces la posición del cambiador.
Las líneas de transmisión están representadas por el circuito equivalente, que se muestra en
la figura 1.5.
Los datos de entrada para cada línea de transmisión son la impedancia y la admitancia de
derivación del circuito equivalente por unidad, los dos buses a los que esta conectada la
línea y la capacidad máxima en MVA. De manera similar, los datos de entrada para cada
transformador son las impedancias de derivación por unidad , la admitancia de la rama de
excitación por unidad , los buses a los que están conectados los devanados y las
capacidades máximas en MVA.
14
2.4 Solucion de flujos de potencia por el método de Newton-Raphson
El número de iteraciones necesarias para obtener una solución es independiente del tamaño
del sistema, pero más evaluaciones funcionales se requieren en cada iteración.
Dado que en el problema de flujo de potencia, la potencia real y la magnitud del voltaje se
especifican para los buses controlados por voltaje, la ecuación de flujo de potencia se formula
en forma polar.
Para el bus típico del sistema de alimentación que muestra en la Figura 2.3, la corriente que
entra al bus viene dada por.
Ec.2.14
Esta ecuación puede ser reescrita en términos de la matriz de admitancia de bus como
Ec.2.15
En la ecuación anterior, j incluye bus i. Expresando esta ecuación en forma polar, tenemos
Ec.2.16
Ec.2.18
15
Separando la parte real e imaginaria
Ec.2.19
Ec.2.20
En el conjunto de ecuaciones anterior, el bus numero 1 es asumido como el bus slack. La matriz
Jacobiana da la relación entre cambios pequeños en el ángulo del voltaje y la magnitud del
elementos de la matriz jacobiana son las derivadas parciales de (2.19) y (2.20), evaluados en
Ec.2.21
Para el bus controlado por voltaje, la magnitud del voltaje es conocida. Por lo tantos si m buses de
el sistema son controlados por voltaje, m ecuaciones involucran y y las columnas
correspondientes en la matriz Jacobiana serán eliminada. Por consiguiente hay restricciones
de potencia real y restricciones de potencia reactiva, y la matriz Jacobiana es de orden
. El es de orden . El es de orden
. El es de orden , y el es de orden .
16
Ec.2.22
Ec.2.23
Ec.2.24
Ec.2.25
Ec.2.26
Ec.2.27
Ec.2.28
Ec.2.29
Los términos y son la diferencia entre el valor previsto y calculado, conocida como
residuo de potencia, dada por
Ec.2.30
Ec.2.31
La nueva estimación para el voltaje de bus son
Ec.2.32
Ec.2.33
El procedimiento para la solución de flujos de potencia por el método de Newton-Raphson es el
siguiente:
ángulo de fase son valores iguales al del bus slack, o 1.0, y . Para
los buses regulado por voltaje, donde y son especificados, el ángulo de fase es
17
Ec.2.34
Ec.2.35
18
CAPITULO 3. PROGRAMA DE FLUJOS DE POTENCIA
Para tener una optima operación de los sistemas de potencia en condiciones normales
balanceadas de estado estable trifásico, se requiere lo siguiente:
En este capitulo se desarrollara el modelo de flujo de carga, el método que se utilizara para la
solución de los flujos de carga será el de Newton-Raphson.
19
3.1 Módulos de programación en PYTHON
Se cuenta con una interfaz para la introducción de datos de manera flexible. La interfaz se ha
realizado en Notepad en donde primeramente se detalla los MVA base que se utilizarían para el
análisis de algún sistema en particular.
A continuación se encuentra lo que son los datos de los buses en donde se introducen los datos
como el nombre del bus, el tipo de bus (en este se coloca si el bus es de tipo PV, PQ o Bus de
referencia con el cual el programa desarrollado entiende la siguiente nomenclatura: se colocara 2 si
el bus es de tipo PV, se colocara 0 si es de tipo PQ, y 1 si es el Bus de referencia), la magnitud de
voltaje del bus, el ángulo en radianes, la demanda (carga) en MW, la demanda (carga) en MVAR,
los MW del generador conectado al bus, los MVAR del generador conectado al bus.
Y por ultimo se encuentra el bloque donde introduciremos los datos de transformadores de tres
devanados, sus resistencias del primario al secundario, del primario al terciario, del secundario al
terciario, y así mismo sus reactancias y susceptancias.
20
3.2 Modulo de Carga
Este genera la carga de datos desde Notepad hasta Python, generando las matrices necesarias de
datos para poder manipularlas como tal. A continuación se presenta la sección del programa
elaborado que lee el archivo de datos, en el mismo hay comentarios explicativos.
21
3.3 Modulo de ybus
22
3.4 Modulo Newton
Este modulo tiene por función hacer todas las iteraciones pertinentes en cuanto a la búsqueda de
la solución del sistema de potencia, considerando las ecuaciones necesarias en el análisis AC de
los sistemas de potencia, empezaremos por describir brevemente las etapas de este modulo.
La primera etapa del diseño de este modulo consta del calculo de potencia con los parámetros de
iniciación del sistema, en otras palabras, las potencias tanto la activa como la reactiva se calculan
con los voltajes y ángulos iníciales introducidos por el usuario.
23
Después de formadas las submatrices hay que formar la matriz Jacobiana completa
Cuando la matriz Jacobiana ya esta completa para la primera iteración y las siguientes que se
formaran se invierte y multiplica por los deltas que para el caso de la primera iteración los deltas
corresponden a los valores inicialmente calculados en la primera etapa de este modulo.
Luego se despejan los nuevos valores calculados para Voltaje y Ángulos y se procede nuevamente
desde la primera etapa hasta lograr la convergencia cuando los deltas de potencia son
comparados que el nivel de tolerancia establecido para nuestro caso de 0.001.
24
3.5 Modulo fpotencia
Una de las aclaraciones que cabe retomar es que cuando el sistema lleva elementos como
transformadores el calculo de los flujos en cada elemento del sistema se vuelve mas complejo, por
lo que cabe señalar que debido a esta consideración se tomo la decisión de calcular primero las
corrientes nodales y en base a ellas obtener las potencias puesto que el voltaje de nodo se conoce.
Así se calculo la potencia compleja S separando sus componentes real e imaginario, a los que se
les denomina potencia activa y potencia reactiva respectivamente.
25
3.6 Modulo salida
El ultimo de los módulos es el modulo que genera el reporte de resultados. Se crea un archivo de
block de notas los resultados de magnitud de voltaje y ángulos en grados de cada uno de los
buses del sistema analizado y a continuación el flujo de potencia real y reactiva de cada unos de
los elementos que conforman el sistema de potencia.
26
3.7 Ejemplo de flujo de potencia
Slack Bus
3
La Figura 3.1 muestra el diagrama unifilar de un sistema de potencia sencillo de tres buses, con
generadores en los buses 1 y 3. La magnitud de voltaje del bus 1 es ajustada a 10.5 p.u. La
magnitud de voltaje en el bus 3 es fijada en 1.04 p.u. con una potencia real de generación de 200
MW. Una carga que consiste de 400 MW y 250 Mvar conectadas al bus 2.
Las impedancias de líneas mostradas se encuentran en por unidad tomando como base 100 MVA,
y la susceptancia de la línea de carga se desprecian. Obtener la solución de flujo de potencia por el
método de Newton-Raphson incluyendo flujos y perdidas en las líneas.
Solución
Las impedancias de línea se convierten en admitancias:
Convirtiendo la matriz de admitancia de bus a forma polar con sus ángulos en radianes
27
Los elementos de la matriz Jacobiana son obtenidas por las derivadas parciales con respecto a ,
y .
El voltaje del bus slack es pu, y en el bus 3 la magnitud del voltaje es pu.
Iniciando con una estimación inicial de , ,y , los residuos de potencia
son calculados con (2.27) y (2.28)
28
El ángulo del voltaje de fase es en radianes. Para la segunda iteración, tenemos
29
Para encontrar los flujos en las líneas, primero se encuentran las corrientes de línea
30
El diagrama de flujo de potencia es mostrado en la figura 3.2, indicando la dirección del flujo tanto
de potencia activa como reactiva.
179.362 170.968
218.423
400
118.734 101.947
39.061 38.878 238.878 229.032
250
140.852
22.118 21.569 167.746 148.053
Flujo en Mvar
Comparando los resultados anteriores con los obtenidos con el programa desarrollado en Python,
los resultados son exactamente los mismos.
31
3.8 Flujo de potencia en un sistema de catorce nodos
El programa realizado en Python se aplicara a un sistema de potencia de catorce nodos figura 3.3,
comparando respuestas con los resultados obtenidos en PSAT.
El sistema esta compuesto por catorce buses, líneas en paralelo, transformadores de dos y tres
devanados, generadores y cargas.
32
Primeramente se introducen los datos a nuestra interfaz como se muestra en la figura 3.4
33
Luego corremos el programa y los resultados son los siguientes:
En los perfiles de voltaje de la simulación se puede apreciar que para los buses de carga los
voltajes de dichos buses son inferiores a los voltajes nominales de cada uno de ellos, esto es
debido al efecto que las cargas producen por la gran demanda de potencia en conjunto con las
perdidas de las líneas de transmisión, lo contrario para los buses de generación o compensadores,
el voltaje se mantiene en su nominal debido a la inyección de potencia y a que en estos las
perdidas de las líneas son compensadas por la generación propia de cada bus.
Los resultados obtenidos se compararon con los resultados que se obtienen de PSAT, teniendo
resultados similares con ambos programas.
34
CAPITULO 4. FLUJO ÓPTIMO DE POTENCIA
4.1 Introduccion
El Flujo Optimo de Potencia (OPF) por sus siglas en ingles, es un problema que fue definido en los
principios del año 1960 como una extensión del problema de despacho económico de carga
convencional, que se utiliza para la determinación óptima de las variables de control en un SEP,
considerando variadas restricciones. OPF, en su formulación general, es un problema de
optimización con función objetivo y restricciones no lineales, que representa la operación en estado
estacionario del sistema eléctrico.
La operación económica significa reducir los costos por la utilización de la energía eléctrica, esto
incluye los costos de producción, transporte y consumo. A pesar de que los costos de transporte de
la energía eléctrica hacia los centros de consumo, podría representar un pequeño porcentaje de los
gastos totales de operación.
Existen variadas funciones objetivos que puede considerar un modelo OPF, entre las cuales se
pueden mencionar (Ristanovic, 1996):
Una gran variedad de técnicas de optimización han sido aplicadas para resolver OPF (Momoh y El-
Hawary, 1999):
· Programación lineal.
· Versiones híbridas de programación lineal y programación entera.
· Métodos de punto interior.
· Programación no lineal.
35
Programación cuadrática.
Soluciones basadas en condiciones de Newton.
Se han considerado varias funciones objetivo en un OPF, pero la que más frecuentemente se usa
toma en cuenta los costos de generación, la que refleja aspectos económicos del sistema de
potencia. De aquí que la formulación matemática del OPF se enfoca en minimizar el costo de
generación de potencia activa por un ajuste adecuado de las variables de control. De forma
general, el OPF puede ser formulado como un problema de optimización no lineal con
restricciones, que matemáticamente se expresa como:
36
El conjunto de restricciones de igualdad, de la ecuación anterior está compuesto por las
ecuaciones de balance de potencia en las barras. Por su parte el conjunto de restricciones de
desigualdad, representa las restricciones del vector de variables de control y de estado, tales como
cotas y límites de operación.
El planteamiento del problema en forma general que se tratara en este trabajo se puede
representar como:
Minimizar
Sujeto a
4.2.2 Variables
G
,
Donde , son variables de control, corresponden a la potencia activa y reactiva inyectadas por
el generador. Por su parte, y θ, son variables de estado, corresponden al módulo de la tensión y
su ángulo respectivamente. y , son parámetros que representan la potencia activa y reactiva
de la carga o consumo.
37
: Angulo de voltaje en el bus i:
: Tap del transformador j:
Ec.4.1
Otro parámetro a considerar es la matriz compleja de admitancia nodal (Y), representada por sus
elementos , que define la relación entre corrientes y tensiones nodales del sistema.
Ec.4.2
Ec.4.3
Si en el arco (ij) existe un transformador, entonces los parámetros de la matriz de admitancia nodal
consideran implícitamente el efecto del tap.
Ec.4.4
Ec.4.5
La minimización de costos por generación de potencia activa conforma la función objetivo para el
OPF considerada en este trabajo.
Para cada generador de la red, se supone conocida su función de costos en las potencias activas
generadas, tal y como se detalla a continuación.
Ec.4.6
38
4.2.4 Restricciones de igualdad
Las restricciones de igualdad son típicamente las ecuaciones de balance de carga, las que se
obtienen al imponer una restricción de balance de potencia activa y reactiva en todos los nodos del
sistema. En un punto de operación en estado estable, la potencia generada debe ser tal que sea
suficiente para cubrir la demanda más las pérdidas en la red. Las ecuaciones de balance
consideran un punto de equilibrio de potencia activa y reactiva que debe satisfacer cada una de los
nodos:
Ec.4.7
Ec.4.8
Ec.4.9
Ec.4.10
Ec.4.11
Las restricciones de desigualdad consideran los límites que deben satisfacer las variables de
control y estado. Estas restricciones reflejan los límites operativos impuestos a los dispositivos y al
sistema eléctrico de potencia. Las principales restricciones de desigualdad consideradas en un
OPF son:
Ec.4.12
Ec.4.13
39
Donde y son los limites de potencia activa mínima y máxima, respectivamente, para el
Límites de flujos en las ramas.- Con la finalidad de mantener la seguridad en los sistemas de
potencia, los enlaces (líneas o transformadores) no deben ser sobrecargados. Por lo tanto, es
necesario definir límites para todas las ramas (o para un grupo de ellas). Estos límites pueden
deberse a restricciones térmicas de los equipos o por consideraciones de seguridad del
sistema. Los límites de los flujos se pueden formular como:
Donde representa el máximo flujo de potencia activa permitido en la rama que conecta
los nodos j e i.
Perfiles de voltaje.- Debido a que el voltaje en los nodos es uno de los criterios de seguridad e
índice de calidad de servicio más importante, incluir una restricción que mejore el perfil de
voltaje de los nodos de carga del sistema es un aspecto importante a ser considerado en el
problema de optimización.
Los voltajes en los nodos de generación son constantes, mientras que el nivel de voltaje en los
nodos de carga debe mantenerse muy cercano a un voltaje de referencia. Matemáticamente esta
restricción se puede definir mediante:
40
4.3 Casos de flujo optimo de potencia (OPF).
4.3.1 OPF de un sistema de dos nodos y modelado AC: sin restricciones de desigualdad. Por
método de Newton-Raphson
En este sistema se busca garantizar una operación segura y encontrar un punto de operación
económico, la operación económica se refiere a reducir los costos por la utilización de la energía
eléctrica esto incluye los costos de producción, transporte y consumo.
Min
Sujeto a:
41
Donde
: Flujo de potencia real que va del nodo 1 al nodo 2
: Flujo de potencia reactiva que va del nodo 1 al nodo 2
Sabemos que:
Análogamente tenemos:
2. Ecuación de LaGrange
42
3. Método de Newton-Raphson
43
: Se conoce como el Hessiano, definido así:
44
Se procederá a resolver el problema mediante el programa elaborado en Python.
Reactancias:
45
Muestra el costo de generación en dólares del generador conectado en el nodo 1, teniendo claro
que este costo es el más económico en lo que respecta a la generación ya que eso es lo que se
buscaba minimizar los costos por generación.
También muestra el valor de las variables duales o costos marginales, las cuales representa la
cantidad en dólares por cada MW producido o demandado, cabe señalar que:
Figura 4.4 Diagrama Unifilar con flujos en las líneas y costos marginales AC
A partir del análisis mostrado del OPF de un sistema de dos nodos modelado AC, podemos
observar que la solución no es trivial ya que el Hessiano formado es demasiado grande, lo cual
para un sistema compuesto por más nodos se complicaría el análisis y la elaboración del
programa. Por ende se opta por enfocarse y enfatizar mas en el modelado DC que se presenta a
continuación.
46
4.3.2 OPF de un sistema multimodal y modelado DC: sin restricciones de desigualdad. Por
método de Newton-Raphson
El supuesto básico del modelo de flujo DC, es que este solo se centra en las potencias activas
tanto en las generadas como las de flujo en las líneas interconectadas entre los buses.
Por lo tanto este análisis se realiza tomando en cuenta las reactancias de línea así como las
potencias generadas como las demandadas. Por lo tanto se asume que no hay cambios en los
voltajes y por tanto no hay generación ni flujos de potencia reactiva.
Ec.4.14
Ec.4.15
Recordando que:
47
Ec.4.16
Donde:
: Potencia activa del nodo i
: Potencia reactiva del nodo i
: Magnitud de voltaje del nodo i
: Magnitud de voltaje del nodo j
: Ángulo de fase del voltaje en el nodo i
: Ángulo de fase del voltaje en el nodo j
: Conductancia de línea entre nodos i-j
: Susceptancia de línea entre nodos i-j
: Resistencia de línea entre nodos i-j
: Reactancia de línea entre nodos i-j
N: Número total de nodos existentes en el sistema
Para modificar el modelo AC de flujo de potencia a un modelo DC, las siguientes simplificaciones
son consideradas:
La magnitud del voltaje en por unidad para cada bus se aproxima a 1 p.u.
La resistencia de línea es ignorada debido a que es muy pequeña comparada con la
reactancia de línea , De esta forma para todas las líneas. Esto implica
entonces que también para todas las líneas. Por lo tanto:
Ec.4.17
Ec.4.21
48
1. Planteamiento
La función a minimizar esta compuesta por las ecuaciones de costos de cada uno de los
generadores del sistema dada por
Ec.4.22
Min Ec.4.23
En donde
: Es la potencia demandada en cada uno de los nodos del sistema; unidades
: Dirección de flujo de potencia de línea interconectada entre lo nodos; unidades
: Potencia generada por cada uno de los generadores conectados a los nodos del sistema;
unidades
: Reactancia de línea interconectada entre los nodos; unidades
A cada ecuación nodal se le asigna un multiplicador de LaGrange ( , , , )
Para el análisis se tomara como referencia
Es de tener en cuenta que estas ecuaciones de balance nodal son las mas importantes en nuestro
análisis ya que a cada una de ellas se les asigna una variable , la cual son llamadas variables
duales, las cuales son los costos marginales del sistema. Es el costo al cual se remunera la
energía producida por cada generador del sistema.
2. Ecuación de LaGrange
49
A continuación planteamos las condiciones de primer orden, que son las derivadas parciales de la
ecuación de LaGrange con respecto a cada una de las variables.
3. Método de Newton-Raphson
50
Para el caso en estudio el Hessiano queda definido como:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0
Por lo tanto:
51
Se procederá a resolver el problema con le programa elaborado en Python.
Reactancias:
Con los datos ya introducidos, procedemos a correr nuestro programa, obteniendo los resultados
siguientes:
52
Primero se observa la magnitud de voltaje en pu de cada uno de los buses del sistema, para el
caso todos constantes ya que se esta haciendo un análisis DC en el cual todas las magnitudes de
voltajes son constantes e iguales a 1.
Al lado de los voltajes se muestran los flujos en las líneas.
Tenemos las potencias generadas por cada generador para poder satisfacer la demanda.
Luego tenemos el costo total de generación en dólares incluyendo ambos generadores.
El programa también reporta, los flujos en las líneas de transmisión, la potencia inyectada por cada
central, los costos marginales nodales.
Las variables duales representan los costos marginales de la demanda en cada nodo y son los
valores con los que remunera la energía producida por cada generador.
Este análisis esta hecho con el objetivo de optimizar las condiciones de operación de un sistema.
Por lo tanto se ha encontrado la solución más económica en producción, transporte y consumo.
A continuación se muestra el diagrama del sistema con todos sus flujos y costos marginales en
cada nodo.
Figura 4.7 Diagrama Unifilar con flujos en las líneas y sus costos marginales DC
53
54
CAPITULO 5. CONCLUSIONES Y RECOMENDACIONES
5.1 Conclusiones
Se desarrollo una aplicación para el OPF en modelado AC, con la limitante del análisis de
un sistema en específico debido a la complejidad de este tipo de modelaje que toma en
cuenta la forma de inyección de la potencia real y reactiva de manera sinusoidal y su
complejidad de programación.
Las simplificaciones efectuadas al modelo AC de OPF, dieron lugar al modelaje DC, para
este ultimo se desarrollo el programa de análisis de OPF manera general pudiéndose
analizar diferentes tipos de sistemas eléctricos desde el punto de vista económico.
5.2 Recomendaciones
Buscar métodos matemáticos alternativos, para una convergencia de solución más rápida
y eficaz en el uso físico de memoria del computador en sistemas grandes.
Elaborar el modelaje de un OPF para análisis de manera general e incluir las restricciones
técnicas de voltaje, ángulo, y límites en la inyección de potencia de los generadores.
55
56
BIBLIOGRAFIA
Duncan Glover J. / Mulukutla S. Sarma. Sistemas de Potencia. Análisis y Diseño. 3ª.ed. México
D.F. 2003. 656 p. ISBN 970-686-291-9.
D.P. Kothari / I.J. Nagrath. Sistemas Eléctricos de Potencia. . 3ª.ed. México D.F. 2008. 685 p. ISBN
0-07-049489-4.
Federico Milano. Power System Modelling and Scripting. ETSII, University of Castilla - La Mancha
13071, Ciudad Real Spain. 551 p. ISBN 978-3-642-13668-9
Juan Eduardo Pérez Retamales. [2001] Flujo de Potencia Optimo con programación cuadrática
secuencial. Tesis para optar al grado de Magister en gestión de operaciones. Facultad de ciencias
físicas y matemáticas, departamento de ingeniería industrial. Universidad de Chile.
Oñate Yumbla Pablo Enrique. [2008] Solución del problema de flujos de potencia optimo con
restricciones de seguridad por un optimizador de partículas modificado. Tesis Doctoral en
Ingeniería Eléctrica. Centro de Investigación y Estudios Avanzados del I.P.N. Unidad Guadalajara.
Saadat Hadi. Power System Analysis. New York: McGraw-Hill. 313 p. ISBN 0-07-012235-0.
Soares Ramos Dorel / Dias Eduardo Mario. Sistemas Eléctricos de Potencia. Regime Permanente.
Volumen 2. Rio de Janeiro: Editora Guanabara Dois S.A. 224 p.
57
58
ANEXO A
PROGRAMA DE FLUJOS DE POTENCIA
59
from cvxopt import matrix, spmatrix, mul, div, sparse
from math import atan, sin, cos, pi
from scipy.linalg import inv
from scipy import conjugate
def carga():#definiendo la función para cargar los datos del archivo interface
f = open('datos14.txt', 'r');
lines = f.readlines();
f.close()
global MVA
#leyendo los MVA base
MVAB=lines[2].split()
MVA=int(MVAB[0])
#leyendo los parametros de buses
ynames = lines[5].split()
y = {}
for name in ynames:
y[name] = []
s=0
while s<1:
for line in lines[6:]:
yvalues = [float(yi) for yi in line.split()]
if len(yvalues) == 0:
break
for name, value in zip(ynames, yvalues):
y[name].append(value)
s+=1
#leyendo los parametros de linea
ul=8+len(y[name])
ul1=ul+1
ynames1 = lines[ul].split()
y1 = {}
for name1 in ynames1:
y1[name1] = []
d=0
1
A-1
while d<1:
for line in lines[ul1:]:
yvalues1 = [float(yi) for yi in line.split()]
if len(yvalues1) == 0:
break
for name1, value1 in zip(ynames1, yvalues1):
y1[name1].append(value1)
d+=1
#leyendo los parametros de lineas en paralelo
ul2=11+len(y[name])+len(y1[name1])
ul3=ul2+1
ynames2 = lines[ul2].split()
y2 = {}
for name2 in ynames2:
y2[name2] = []
e=0
while e<1:
for line in lines[ul3:]:
yvalues2 = [float(yi) for yi in line.split()]
if len(yvalues2) == 0:
break
for name2, value2 in zip(ynames2, yvalues2):
y2[name2].append(value2)
e+=1
#leyendo los parametros de transformadores de 2 devanados
ul4=14+len(y[name])+len(y1[name1])+len(y2[name2])
ul5=ul4+1
ynames3 = lines[ul4].split()
y3 = {}
for name3 in ynames3:
y3[name3] = []
f=0
while f<1:
for line in lines[ul5:]:
yvalues3 = [float(yi) for yi in line.split()]
if len(yvalues3) == 0:
break
A-2
2
for name3, value3 in zip(ynames3, yvalues3):
y3[name3].append(value3)
f+=1
#leyendo los parámetros de transformadores de 3 devanados
ul6=17+len(y[name])+len(y1[name1])+len(y2[name2])+len(y3[name3])
ul7=ul6+1
ynames4 = lines[ul6].split()
y4 = {}
for name4 in ynames4:
y4[name4] = []
g=0
while g<1:
for line in lines[ul7:]:
yvalues4 = [float(yi) for yi in line.split()]
if len(yvalues4) == 0:
break
for name4, value4 in zip(ynames4, yvalues4):
y4[name4].append(value4)
g+=1
#generando matrices de datos
global nbr4,nlt,nnbus,anges,tbus,V,nombus,pes,qes,nbr,nl,nr,R,x,lip,lsp,lipr,lspr,B,A
#datos de buses
nnbus=len(y['nombre'])# numero de buses del sistema
anges=matrix(y['rad'],(nnbus,1))
tbus=matrix(y['bus'],(nnbus,1))#bus PQ=0, bus PV=2, bus referencia=1
V=matrix(y['vol'],(nnbus,1))
nombus=matrix(y['nombre'],(nnbus,1))
prload=matrix(y['loadMW'],(nnbus,1))
preacload=matrix(y['loadMvar'],(nnbus,1))
prgene=matrix(y['generaMW'],(nnbus,1))
preacgene=matrix(y['generaMvar'],(nnbus,1))
lip=matrix(y['lpinf'],(nnbus,1))
lsp=matrix(y['lpsup'],(nnbus,1))
lipr=matrix(y['lprinf'],(nnbus,1))
lspr=matrix(y['lprsup'],(nnbus,1))
A-3
3
A-1
nbr1=len(y1['nl'])# numero de lineas del sistema
nomlin=matrix(y1['nomlin'],(nbr1,1))#nombre de linea
nl1=matrix(y1['nl'],(nbr1,1))#linea desde
nr1=matrix(y1['nr'],(nbr1,1))#linea hasta
R1=matrix(y1['R'],(nbr1,1))# resitencia de linea
x1=matrix(y1['X'],(nbr1,1))#reactancia de linea
B1=matrix(y1['B'],(nbr1,1))#suceptancia de linea
A1=matrix(y1['a'],(nbr1,1))#linea o tranformador
plpd=0
plph=0
cb=0
cdl=0
cp=0
#conteo de bloques de lineas en paralelo
if nbr2!=0:
for k in range(0,nbr2-1):
if nlp1[k]!=nlp1[k+1] or nrp1[k]!=nrp1[k+1]:
cp+=1
cp=cp+1
# conteo lineas en cada bloque
lan=spmatrix([],[],[],(cp,1),tc='d')
nlpf=spmatrix([],[],[],(cp,1),tc='d')
nrpf=spmatrix([],[],[],(cp,1),tc='d')
req=spmatrix([],[],[],(cp,1),tc='d')
xeq=spmatrix([],[],[],(cp,1),tc='d')
beq=spmatrix([],[],[],(cp,1),tc='d')
4
A-4
Ap=matrix(1,(cp,1),tc='d')
if cp>1:
j=spmatrix([],[],[],(cp+1,1),tc='d')
if cp==1:
j=spmatrix([],[],[],(cp,1),tc='d')
for k in range(0,nbr2):
lp[k]=nomlinp[k]-nbr1-1
if lp[k]==0:
plpd=int(nlp1[k])
plph=int(nrp1[k])
nlpf[cb]=plpd
nrpf[cb]=plph
j[cb]=0
if lp[k]!=0:
if nlp1[k]==plpd and nrp1[k]==plph:
cdl+=1
else:
plpd=int(nlp1[k])
plph=int(nrp1[k])
j[cb+1]=k
nlpf[cb+1]=plpd
nrpf[cb+1]=plph
cdl+=1
lan[cb]=cdl
cdl=0
cb+=1
if cp-1==cb and lp[k]==nbr2-1 and cp>1:
cdl+=1
lan[cb]=cdl
j[cb+1]=k
if cp==1:
cdl+=1
lan[cb]=cdl
nlpf[cb]=plpd
nrpf[cb]=plph
j[cb]=cdl
#calculo de parametros lineas en paralelo
5
A-5
if cp>1:
for k in range(0,cp):
if cp-1>k:
for i in range(int(j[k]),int(j[k+1])):
req[k]=req[k]+1/(Rp[i])
xeq[k]=xeq[k]+1/(xp[i])
beq[k]=beq[k]+1/(Bp[i])
req[k]=1/req[k]
xeq[k]=1/xeq[k]
beq[k]=1/beq[k]
if cp-1==k:
for i in range(int(j[k]),int(j[k+1])+1):
req[k]=req[k]+1/(Rp[i])
xeq[k]=xeq[k]+1/(xp[i])
beq[k]=beq[k]+1/(Bp[i])
req[k]=1/req[k]
xeq[k]=1/xeq[k]
beq[k]=1/beq[k]
if cp==1:
for k in range(0,cp):
for i in range(0,int(j[k])):
req[k]=req[k]+1/(Rp[i])
xeq[k]=xeq[k]+1/(xp[i])
beq[k]=beq[k]+1/(Bp[i])
req[k]=1/req[k]
xeq[k]=1/xeq[k]
beq[k]=1/beq[k]
6
A-6
A2=matrix(y3['a2'],(nbr3,1))#relacion de tranformacion
7
A-7
x32[k]=0.5*(xps[k]-xpt[k]+xst[k])
x33[k]=0.5*(-xps[k]+xpt[k]+xst[k])
x12[k]=x31[k]+x32[k]
x13[k]=x31[k]+x33[k]
#resistencia
r31[k]=0.5*(rps[k]+rpt[k]-rst[k])
r32[k]=0.5*(rps[k]-rpt[k]+rst[k])
r33[k]=0.5*(-rps[k]+rpt[k]+rst[k])
r12[k]=r31[k]+r32[k]
r13[k]=r31[k]+r33[k]
#susceptancia
b31[k]=0.5*(bps[k]+bpt[k]-bst[k])
b32[k]=0.5*(bps[k]-bpt[k]+bst[k])
b33[k]=0.5*(-bps[k]+bpt[k]+bst[k])
b12[k]=b31[k]+b32[k]
b13[k]=b31[k]+b33[k]
nbr=nbr1+cp+nbr3+3*nbr4
# Dimension de matrices si existen lineas en paralelo
if nbr2!=0:
A=sparse([A1,Ap,A2,A3,1,1])
A=matrix(A)
nlt=sparse([nomlin,nomlinp,nomt2,nomt3])
nlt=matrix(nlt)
R=sparse([R1,req,R2,r31,r32,r33])
R=matrix(R)
x=sparse([x1,xeq,x2,x31,x32,x33])
x=matrix(x)
B=sparse([B1,beq,B2,b31,b32,b33])
B=matrix(B)
nl=sparse([nl1,nlpf,nlt2,nlp2,nc,nc])
nl=matrix(nl)
nr=sparse([nr1,nrpf,nrt2,nc,np12,np13])
nr=matrix(nr)
#Dimension de matrices si no existen lineas en paralelo
if nbr2==0:
A=sparse([A1,A2,A3,1,1])
A=matrix(A)
8
A-8
nlt=sparse([nomlin,nomt2,nomt3])
nlt=matrix(nlt)
R=sparse([R1,R2,r31,r32,r33])
R=matrix(R)
x=sparse([x1,x2,x31,x32,x33])
x=matrix(x)
B=sparse([B1,B2,b31,b32,b33])
B=matrix(B)
nl=sparse([nl1,nlt2,nlp2,nc,nc])
nl=matrix(nl)
nr=sparse([nr1,nrt2,nc,np12,np13])
nr=matrix(nr)
9
A-9
Ypi=spmatrix([],[],[],(nnbus,nnbus))
Ypm=spmatrix([],[],[],(nnbus,nnbus))
Ypa=spmatrix([],[],[],(nnbus,nnbus))
#iniciando la formacion de Ybus, en rectangular
int()
s=0
cx=0
bx=0
while s<=nbr-1:
int(x[s,0])
cx=matrix(x[s]*1j)
xc[s,0]=cx
int(B[s,0])
bx=matrix(B[s]*1j)
bc[s,0]=bx
s+=1
z=R+xc
ds=div(y,z)
#Ybus fuera de la diagonal
for d in range(0,nbr):
if nl[d] > 0 and nr[d] > 0:
x0=int(nl[d])-1
y0=int(nr[d])-1
Y[x0,y0]=Y[x0,y0]-ds[d]/A[d]
Y[y0,x0]=Y[x0,y0]
#Ybus en la diagonal
for n in range(0,nnbus):
for k in range(0,nbr):
x1[k]=int(nl[k])-1
y1[k]=int(nr[k])-1
if x1[k]==n:
Y[n,n]=Y[n,n]+ ds[k]/(A[k]**2)+bc[k]/2
if y1[k]==n:
Y[n,n]=Y[n,n]+ ds[k]+bc[k]/2
10
A-10
for k in range(0,nnbus):
Ypr[n,k]=Y[n,k].real
Ypi[n,k]=Y[n,k].imag
#magnitud de Ybus
Ypm[n,k]=abs(Y[n,k])
if Ypr[n,k] > 0 or Ypr[n,k] < 0:
if n==k:
#angulo de Ybus en la diagonal
Ypa[n,k]=atan(Ypi[n,k]/Ypr[n,k])
if n<k or n>k:
#angulo de Ybus fuera de la diagonal
Ypa[n,k]=atan(Ypi[n,k]/Ypr[n,k])+pi
if Ypr[n,k]==0 and Ypi[n,k]>0:
Ypa[n,k]=pi/2
if Ypr[n,k]==0 and Ypi[n,k]<0:
Ypa[n,k]=-pi/2
return Y
11
A-11
aa=0
bb=0
for i in range(0,nnbus):
for k in range(0,nnbus):
#calculo de potencia real
pcal[i]= pcal[i]+ V[i]*Ypm[i,k]*V[k]*cos(Ypa[i,k]+anges[k]-anges[i])
#calculo de potencia reactiva
qcal[i]= qcal[i]-V[i]*Ypm[i,k]*V[k]*sin(Ypa[i,k]+anges[k]-anges[i])
bac=matrix(1,(cbpvpq,1),tc='d')
bacaux=matrix(1,(cbpvpq,1),tc='d')
bacc=0
for i in range(1,nnbus):
if tbuscam[i]==0:
12
A-12
bac[bacc]=nombus[i]
bacc+=1
for i in range(0,cbpvpq):
bacaux[i]=int(bac[i])-1
#conteo de buses PV y PQ
for a in range(0,nnbus):
if tbus[a] ==2:
aa = aa+1
if tbus[a] == 0:
bb = bb+1
#Declarcion de matrices
dpi=spmatrix([],[],[],(nnbus-1,1))
dqi=spmatrix([],[],[],(omj2,1))
j1=matrix(0,(omj1,omj1),tc='d')
j2=matrix(0,(omj1,omj2),tc='d')
j3=matrix(0,(omj2,omj1),tc='d')
j4=matrix(0,(omj2,omj2),tc='d')
jp=spmatrix([],[],[],(omj1,omj1))
jp1=spmatrix([],[],[],(omj1,omj1))
jp2=spmatrix([],[],[],(omj1,omj1))
npq=spmatrix([],[],[],(omj2,1))
pq=spmatrix([],[],[],(omj2,1))
jin=spmatrix([],[],[],(omj,omj))
mav3=spmatrix([],[],[],(nnbus,nnbus))
13
A-13
sang=spmatrix([],[],[],(nnbus,nnbus))
cang=spmatrix([],[],[],(nnbus,nnbus))
mav2=spmatrix([],[],[],(nnbus,nnbus))
pang=spmatrix([],[],[],(nnbus-1,nnbus-1))
pvol=spmatrix([],[],[],(nnbus-1,nnbus-1))
qang=spmatrix([],[],[],(nnbus-1,nnbus-1))
qvol=spmatrix([],[],[],(nnbus-1,nnbus-1))
mdpi=0
e=0
c=0
#seleccion de buses PQ
for b in range(0,nnbus):
if tbus[b]==0:
pq[c]=int(nombus[b])-1
c+=1
d=0
#calculo de delta potencia real
for i in range(1,nnbus):
dpi[i-1]= pes[i]-pcal[i]
if tbus[i]==0:
#calculo de delta potencia reactiva
dqi[d]= qes[int(pq[d])]-qcal[int(pq[d])]
d+=1
14
A-14
f+=1
#elementos que conformaran las submatrices jacobianas
for p in range(0,nnbus):
for q in range(0,nnbus):
if p<q or p>q:
mav3[q,p]=V[p]*V[q]*Ypm[p,q]
mav2[q,p]=V[q]*Ypm[p,q]
sang[q,p]=sin(Ypa[p,q]+anges[p]-anges[q])
cang[q,p]=cos(Ypa[p,q]+anges[p]-anges[q])
for p in range(1,nnbus):
for q in range(1,nnbus):
if p<q or p>q:
pang[q-1,p-1]=-mav3[q,p]*sang[q,p]#elementos para j1
pvol[q-1,p-1]=mav2[q,p]*cang[q,p]#elementos para j2
qang[q-1,p-1]=-mav3[q,p]*cang[q,p]#elementos para j3
qvol[q-1,p-1]=-mav2[q,p]*sang[q,p]#elementos para j4
#fuera de diagonal de j1
for p in range(0,omj1):
for q in range(0,omj1):
if p<q or p>q:
j1[q,p]=pang[q,p]
#diagonal j1
for i in range(1,omj1+1):
for j in range(0,nnbus):
if i>j or i<j:
j1[i-1,i-1]=j1[i-1,i-1]+V[i]*V[j]*Ypm[i,j]*sin(Ypa[i,j]-anges[i]+anges[j])
#diagonal de j2
for i in range(1,omj1+1):
for j in range(0,nnbus):
jp1[i-1,i-1]=jp1[i-1,i-1]+V[j]*Ypm[i,j]*cos(Ypa[i,j]-anges[i]+anges[j])
jp1[i-1,i-1]=jp1[i-1,i-1]+V[i]*Ypm[i,i]*cos(Ypa[i,i])
for i in range(0,omj1):
pvol[i,i]=jp1[i,i]
15
A-15
#diagonal de j3
for i in range(1,omj1+1):
for j in range(0,nnbus):
if i>j or i<j:
jp[i-1,i-1]=jp[i-1,i-1]+V[i]*V[j]*Ypm[i,j]*cos(Ypa[i,j]-anges[i]+anges[j])
for i in range(0,omj1):
qang[i,i]=jp[i,i]
#diagonal para j4
for i in range(1,omj1+1):
for j in range(0,nnbus):
jp2[i-1,i-1]=jp2[i-1,i-1]+V[j]*Ypm[i,j]*sin(Ypa[i,j]-anges[i]+anges[j])
jp2[i-1,i-1]=jp2[i-1,i-1]+V[i]*Ypm[i,i]*sin(Ypa[i,i])
for i in range(0,omj1):
qvol[i,i]=-jp2[i,i]
sj2=0
for i in range(0,nnbus):
if tbus[i]==0:
npq[sj2]=int(nombus[i])-2
sj2+=1
sj3=0
s1=0
#fuera de diagonal de j2
for i in range(0,omj2):
s1=int(npq[i])
for j in range(0,omj1):
j2[j,sj3]=pvol[j,s1]
sj3+=1
sj4=0
s2=0
#fuera de diagonal de j3
for i in range(0,omj2):
16
A-16
s2=int(npq[i])
for j in range(0,omj1):
j3[sj4,j]=qang[s2,j]
sj4+=1
sj5=0
sj6=0
s3=0
s4=0
#fuera de diagonal de j4
for i in range(0,omj2):
s3=int(npq[i])
for j in range(0,omj2):
if sj5==omj2:
sj5=0
s4=int(npq[j])
j4[sj6,sj5]=qvol[s3,s4]
sj5+=1
sj6+=1
17
A-17
#invirtiendo la matriz jacobiana
jin=inv(jac)
jjin=matrix(jin,(omj,omj))
deltas= mul(jjin*delta)
#despejando incognitas, angulos y voltajes
iterac=ite+deltas
#introduciendo los nuevos angulos y voltajes en sus respectivas
#matrices para la nueva iteracion
for i in range(0,omj):
if i<omj1:
anges[i+1]=iterac[i]
ite[i]=iterac[i]
if i>=omj1:
V[int(pq[e])]=iterac[i]
ite[i]=iterac[i]
e+=1
#variables que calculan el error entre los varoles para
#obtener los deltas verificando convergencia segun la tolerancia
dip=max(abs(dpi))
diq=max(abs(dqi))
it+=1
18
A-18
for k in range(0,nnbus):
Vc[k] = V[k]*cos(anges[k])+V[k]*sin(anges[k])*1j
for k in range(0,nbr):
i=int(nl[k])-1
j=int(nr[k])-1
Ii[k]=(Vc[i]-A[k]*Vc[j])*ds[k]/(A[k]**2)+bc[k]*Vc[i]/(2*A[k]**2)
Ij[k]=(Vc[j]-Vc[i]/A[k])*ds[k]+bc[k]*Vc[j]/2
sij[k]=Vc[i]*conjugate(Ii[k])*MVA
sji[k]=Vc[j]*conjugate(Ij[k])*MVA
fp[k]=sij[k].real
fq[k]=sij[k].imag
fpdi[k]=sji[k].real
fqdi[k]=sji[k].imag
ppr[k]=abs(abs(fp[k])-abs(fpdi[k]))
ppre[k]=abs(abs(fq[k])-abs(fqdi[k]))
return fp, fq
19
A-19
# imprimiendo flujo en las lineas
f.write('\n')
f.write('Potencia real MW\n')
f.write('De hasta\n')
#print 'Potencia real en MW'
for k in range(0,nbr):
i=int(nl[k])-1
j=int(nr[k])-1
f.write(str(i+1)+' '+str(j+1)+' ')
f.write(format %fp[k]+'\n')
#print
f.write('\n')
f.write('Potencia reactiva MVAR\n')
f.write('De hasta\n')
for k in range(0,nbr):
i=int(nl[k])-1
j=int(nr[k])-1
f.write(str(i+1)+' '+str(j+1)+' ')
f.write(format %fq[k]+'\n')
#print
A-20
20
f.write('De hasta\n')
for k in range(0,nbr):
i=int(nr[k])-1
j=int(nl[k])-1
f.write(str(i+1)+' '+str(j+1)+' ')
f.write(format %fqdi[k]+'\n')
#print
def apertura():
import os
print 'Abriendo reporte.....'
archivo=os.popen('reporte'+str(nnbus)+'buses.txt')
21
A-21
22
ANEXO B
PROGRAMA DE FLUJO ÓPTIMO DE POTENCIA (OPF)
MODELO AC
23
24
from cvxopt import matrix, spmatrix, mul, div, sparse
from math import atan, sin, cos, pi
from scipy.linalg import inv
from scipy import conjugate
def carga():#definiendo la función para cargar los datos del archivo de datos
f = open('ac2.txt', 'r');
lines = f.readlines();
f.close()
global MVA
#leyendo los Mvar base del archivo de block de notas
MVAB=lines[2].split()
MVA=int(MVAB[0])
#leyendo los parámetros de buses
ynames = lines[5].split()
y = {}
for name in ynames:
y[name] = []
s=0
while s<1:
for line in lines[6:]:
yvalues = [float(yi) for yi in line.split()]
if len(yvalues) == 0:
break
for name, value in zip(ynames, yvalues):
y[name].append(value)
s+=1
#leyendo los parámetros de línea
ul=8+len(y[name])
ul1=ul+1
ynames1 = lines[ul].split()
y1 = {}
for name1 in ynames1:
y1[name1] = []
d=0
while d<1:
for line in lines[ul1:]:
1
B-1
yvalues1 = [float(yi) for yi in line.split()]
if len(yvalues1) == 0:
break
for name1, value1 in zip(ynames1, yvalues1):
y1[name1].append(value1)
d+=1
#leyendo los parámetros de líneas en paralelo
ul2=11+len(y[name])+len(y1[name1])
ul3=ul2+1
ynames2 = lines[ul2].split()
y2 = {}
for name2 in ynames2:
y2[name2] = []
e=0
while e<1:
for line in lines[ul3:]:
yvalues2 = [float(yi) for yi in line.split()]
if len(yvalues2) == 0:
break
for name2, value2 in zip(ynames2, yvalues2):
y2[name2].append(value2)
e+=1
#leyendo los parámetros de transformadores de 2 devanados
ul4=14+len(y[name])+len(y1[name1])+len(y2[name2])
ul5=ul4+1
ynames3 = lines[ul4].split()
y3 = {}
for name3 in ynames3:
y3[name3] = []
f=0
while f<1:
for line in lines[ul5:]:
yvalues3 = [float(yi) for yi in line.split()]
if len(yvalues3) == 0:
break
for name3, value3 in zip(ynames3, yvalues3):
y3[name3].append(value3)
2
B-2
f+=1
#leyendo los parámetros de transformadores de 3 devanados
ul6=17+len(y[name])+len(y1[name1])+len(y2[name2])+len(y3[name3])
ul7=ul6+1
ynames4 = lines[ul6].split()
y4 = {}
for name4 in ynames4:
y4[name4] = []
g=0
while g<1:
for line in lines[ul7:]:
yvalues4 = [float(yi) for yi in line.split()]
if len(yvalues4) == 0:
break
for name4, value4 in zip(ynames4, yvalues4):
y4[name4].append(value4)
g+=1
3
B-3
cc=matrix(y['c'],(nnbus,1))
lam=matrix(y['l'],(nnbus,1))
# parametros de las lineas
plpd=0
plph=0
cb=0
cdl=0
cp=0
if nbr2!=0:
for k in range(0,nbr2-1):#conteo de cuantos bloques de líneas hay en //
if nlp1[k]!=nlp1[k+1] or nrp1[k]!=nrp1[k+1]:
cp+=1
cp=cp+1
lan=spmatrix([],[],[],(cp,1),tc='d')
nlpf=spmatrix([],[],[],(cp,1),tc='d')
nrpf=spmatrix([],[],[],(cp,1),tc='d')
req=spmatrix([],[],[],(cp,1),tc='d')
4
B-4
xeq=spmatrix([],[],[],(cp,1),tc='d')
beq=spmatrix([],[],[],(cp,1),tc='d')
Ap=matrix(1,(cp,1),tc='d')
if cp>1:
j=spmatrix([],[],[],(cp+1,1),tc='d')
if cp==1:
j=spmatrix([],[],[],(cp,1),tc='d')
for k in range(0,nbr2):# conteo de cuantas líneas hay en cada bloque
lp[k]=nomlinp[k]-nbr1-1
if lp[k]==0:
plpd=int(nlp1[k])
plph=int(nrp1[k])
nlpf[cb]=plpd
nrpf[cb]=plph
j[cb]=0
if lp[k]!=0:
if nlp1[k]==plpd and nrp1[k]==plph:
cdl+=1
else:
plpd=int(nlp1[k])
plph=int(nrp1[k])
j[cb+1]=k
nlpf[cb+1]=plpd
nrpf[cb+1]=plph
cdl+=1
lan[cb]=cdl
cdl=0
cb+=1
if cp-1==cb and lp[k]==nbr2-1 and cp>1:
cdl+=1
lan[cb]=cdl
j[cb+1]=k
if cp==1:
cdl+=1
lan[cb]=cdl
nlpf[cb]=plpd
nrpf[cb]=plph
5
B-5
j[cb]=cdl
#print j
#calculo de los parámetros de las líneas en //
if cp>1:
for k in range(0,cp):
if cp-1>k:
for i in range(int(j[k]),int(j[k+1])):
req[k]=req[k]+1/(Rp[i])
xeq[k]=xeq[k]+1/(xp[i])
beq[k]=beq[k]+1/(Bp[i])
req[k]=1/req[k]
xeq[k]=1/xeq[k]
beq[k]=1/beq[k]
if cp-1==k:
for i in range(int(j[k]),int(j[k+1])+1):
req[k]=req[k]+1/(Rp[i])
xeq[k]=xeq[k]+1/(xp[i])
beq[k]=beq[k]+1/(Bp[i])
req[k]=1/req[k]
xeq[k]=1/xeq[k]
beq[k]=1/beq[k]
if cp==1:
for k in range(0,cp):
for i in range(0,int(j[k])):
req[k]=req[k]+1/(Rp[i])
xeq[k]=xeq[k]+1/(xp[i])
beq[k]=beq[k]+1/(Bp[i])
req[k]=1/req[k]
xeq[k]=1/xeq[k]
beq[k]=1/beq[k]
#print req
#print plph
#parámetros de transformadores de 2 devanados
nbr3=len(y3['nl2t'])# numero de transformadores de 2 dev
nomt2=matrix(y3['nomtransf2'],(nbr3,1))#nombre de transformador
nlt2=matrix(y3['nl2t'],(nbr3,1))#desde
6
B-6
nrt2=matrix(y3['nr2t'],(nbr3,1))#hasta
R2=matrix(y3['R2'],(nbr3,1))# resistencia
x2=matrix(y3['X2'],(nbr3,1))#reactancia
B2=matrix(y3['B2'],(nbr3,1))#susceptancia
A2=matrix(y3['a2'],(nbr3,1))#relación de transformación
7
B-7
b13=spmatrix([],[],[],(nbr4,1),tc='d')
#baux=spmatrix([],[],[],(nbr4,1),tc='d')
for k in range(0,nbr4):
x31[k]=0.5*(xps[k]+xpt[k]-xst[k])#reactancia
x32[k]=0.5*(xps[k]-xpt[k]+xst[k])
x33[k]=0.5*(-xps[k]+xpt[k]+xst[k])
x12[k]=x31[k]+x32[k]
x13[k]=x31[k]+x33[k]
r31[k]=0.5*(rps[k]+rpt[k]-rst[k])#resistencia
r32[k]=0.5*(rps[k]-rpt[k]+rst[k])
r33[k]=0.5*(-rps[k]+rpt[k]+rst[k])
r12[k]=r31[k]+r32[k]
r13[k]=r31[k]+r33[k]
b31[k]=0.5*(bps[k]+bpt[k]-bst[k])#susceptancia
b32[k]=0.5*(bps[k]-bpt[k]+bst[k])
b33[k]=0.5*(-bps[k]+bpt[k]+bst[k])
b12[k]=b31[k]+b32[k]
b13[k]=b31[k]+b33[k]
nbr=nbr1+cp+nbr3+3*nbr4
8
B-8
if nbr2==0:#si no hay líneas en //
A=sparse([A1,A2,A3,1,1])
A=matrix(A)
nlt=sparse([nomlin,nomt2,nomt3])
nlt=matrix(nlt)
R=sparse([R1,R2,r31,r32,r33])
R=matrix(R)
x=sparse([x1,x2,x31,x32,x33])
x=matrix(x)
B=sparse([B1,B2,b31,b32,b33])
B=matrix(B)
nl=sparse([nl1,nlt2,nlp2,nc,nc])
nl=matrix(nl)
nr=sparse([nr1,nrt2,nc,np12,np13])
nr=matrix(nr)
#potencias en p.u
pes=spmatrix([],[],[],(nnbus,1))
qes=spmatrix([],[],[],(nnbus,1))
for i in range(0,nnbus): # generando los valores de potencia en p.u
pes[i]=(prgene[i]-prload[i])/MVA
qes[i]=(preacgene[i]-preacload[i])/MVA
9
B-9
#iniciando la formacion de Ybus llamdo Y en rectangular
int()
s=0
cx=0
bx=0
while s<=nbr-1:
int(x[s,0])
cx=matrix(x[s]*1j)
xc[s,0]=cx
int(B[s,0])
bx=matrix(B[s]*1j)
bc[s,0]=bx
s+=1
z=R+xc
ds=div(y,z)
#print ds
# Ybus fuera de la diagonal
for d in range(0,nbr):
if nl[d] > 0 and nr[d] > 0:
x0=int(nl[d])-1
y0=int(nr[d])-1
Y[x0,y0]=Y[x0,y0]-ds[d]/A[d]
Y[y0,x0]=Y[x0,y0]
# Ybus en la diagonal
for n in range(0,nnbus):
for k in range(0,nbr):
x1[k]=int(nl[k])-1
y1[k]=int(nr[k])-1
if x1[k]==n:
Y[n,n]=Y[n,n]+ ds[k]/(A[k]**2)+bc[k]/2
if y1[k]==n:
Y[n,n]=Y[n,n]+ ds[k]+bc[k]/2
10
B-10
Ypi[n,k]=Y[n,k].imag
Ypm[n,k]=abs(Y[n,k]) # magnitud de Ybus
if Ypr[n,k] > 0 or Ypr[n,k] < 0:
if n==k:
Ypa[n,k]=atan(Ypi[n,k]/Ypr[n,k]) # angulo de Ybus en la diagonal
if n<k or n>k:
Ypa[n,k]=atan(Ypi[n,k]/Ypr[n,k])+pi # angulo de Ybus fuera de la diagonal
if Ypr[n,k]==0 and Ypi[n,k]>0:
Ypa[n,k]=pi/2
if Ypr[n,k]==0 and Ypi[n,k]<0:
Ypa[n,k]=-pi/2
return Y
lini=spmatrix([],[],[],(nnbus,1),tc='d')
ppcal=spmatrix([],[],[],(nnbus,1),tc='d')
Vi=spmatrix([],[],[],(nnbus,1),tc='d')
angi=spmatrix([],[],[],(nnbus,1),tc='d')
lamdas=spmatrix([],[],[],(2*nnbus,1),tc='d')
bgene=0
for i in range(0,nnbus):
Vi[i-1]=V[i]#voltaje inicial
angi[i]=anges[i]#angulo inicial
if cc[i]>0:
bgene+=1
dx=4*bgene+4*(nnbus-1)
busgene=spmatrix([],[],[],(bgene,1))
dlpg=spmatrix([],[],[],(nnbus,1))
dlt=spmatrix([],[],[],(nbr,1))
dll=spmatrix([],[],[],(nnbus,1))
busl=spmatrix([],[],[],(nnbus-bgene,1))
hes=matrix(0,(dx,dx),tc='d')
hesin=spmatrix([],[],[],(dx,dx))
grad=spmatrix([],[],[],(dx,1))
pig=spmatrix([],[],[],(bgene,1))
11
B-11
xnueva=spmatrix([],[],[],(dx,1),tc='d')
a=0
for i in range(0,nnbus):
if cv[i]>0:
busgene[a]=nombus[i]
a+=1
b=0
for i in range(0,nnbus):
if cv[i]==0:
busl[b]=nombus[i]
b+=1
c=0
for i in range(0,nnbus):
if cv[i]>0:
pig[c]=prgene[int(busgene[c])-1]
c+=1
for i in range(0,nnbus-1):
y=sparse([angi[i+1],Vi[i+1],prgene[i],preacgene[i],lam,lr])# matriz de incognitas iniciales
#print y
for k in range(0,1):
if k==0:
p21=Vi[k+1]*Vi[k+1]*Ypm[k,k]*cos(Ypa[k,k])-Vi[k]*Vi[k+1]*Ypm[k,k]*cos(angi[k]+Ypa[k,k]
-angi[k+1])
12
B-12
p12=Vi[k]*Vi[k]*Ypm[k,k]*cos(Ypa[k,k])-Vi[k]*Vi[k+1]*Ypm[k,k]*cos(angi[k+1]+Ypa[k,k]
-angi[k])
q21=Vi[k+1]*Vi[k+1]*Ypm[k,k]*sin(Ypa[k,k])-Vi[k]*Vi[k+1]*Ypm[k,k]*sin(angi[k]+Ypa[k,k]
-angi[k+1])
q12=Vi[k]*Vi[k]*Ypm[k,k]*sin(Ypa[k,k])-Vi[k]*Vi[k+1]*Ypm[k,k]*sin(angi[k+1]+Ypa[k,k]
- angi[k])
grad[k]=Vi[k]*Vi[k+1]*Ypm[k,k]*(lam[k]*sin(angi[k+1]+Ypa[k,k]-angi[k])
- lam[k+1]*sin(angi[k]+Ypa[k,k]-angi[k+1])-lr[k]*cos(angi[k+1]+Ypa[k,k]
-angi[k])+lr[k+1]*cos(angi[k]+Ypa[k,k]-angi[k+1]))
grad[k+1]=-lam[k]*Vi[k]*Ypm[k,k]*cos(angi[k+1]+Ypa[k,k]-
-angi[k])+lam[k+1]*(2*Vi[k+1]*Ypm[k,k]*cos(Ypa[k,k])
-Vi[k]*Ypm[k,k]*cos(angi[k]+Ypa[k,k]
- angi[k+1]))-lr[k]*Vi[k]*Ypm[k,k]*sin(angi[k+1]+Ypa[k,k]
- angi[k])+lr[k+1]*Ypm[k,k]*(2*Vi[k+1]*sin(Ypa[k,k])-Vi[k]*sin(angi[k]+Ypa[k,k]
-angi[k+1]))
grad[k+2]=cv[k]+2*cc[k]*prgene[k]-lam[k]/MVA
grad[k+3]=-lr[k]/MVA
grad[k+4]=prload[k]/MVA+p12-prgene[k]/MVA
grad[k+5]=prload[k+1]/MVA+p21
grad[k+6]=preacload[k]/MVA+q12-preacgene[k]/MVA
grad[k+7]=preacload[k+1]/MVA+q21
for k in range(0,1):
for j in range(0,1):
if j==0:
gam=angi[j+1]+Ypa[j]-angi[j]
bet=angi[j]+Ypa[j]-angi[j+1]
if k==0:
hes[k,k]=Vi[k]*Vi[k+1]*Ypm[k,k]*(lam[k]*cos(gam)+lam[k+1]*cos(bet)+lr[k]*sin(gam)
+lr[k+1]*sin(bet))
hes[k+1,j]=Vi[k]*Ypm[k,k]*(lam[k]*sin(gam)-lam[k+1]*sin(gam)
- lr[k]*cos(gam)+lr[k+1]*cos(bet))
hes[k+4,j]=Vi[k]*Vi[k+1]*Ypm[k,k]*sin(gam)
hes[k+5,j]=-Vi[k]*Vi[k+1]*Ypm[k,k]*sin(bet)
hes[k+6,j]=-Vi[k]*Vi[k+1]*Ypm[k,k]*cos(gam)
hes[k+7,j]=Vi[k]*Vi[k+1]*Ypm[k,k]*cos(bet)
13
B-13
hes[k,j+1]=Vi[k]*Ypm[k,k]*(lam[k]*sin(gam)-lam[k+1]*sin(bet)
-lr[k]*cos(gam)+lr[k+1]*cos(bet))
hes[k+1,j+1]=2*Ypm[k,k]*(lam[k+1]*cos(Ypa[k])+lr[k+1]*sin(Ypa[k]))
hes[k+4,j+1]=-Vi[k]*Ypm[k,k]*cos(gam)
hes[k+5,j+1]=2*Vi[k+1]*Ypm[k,k]*cos(Ypa[k])-Vi[k]*Ypm[k,k]*cos(bet)
hes[k+6,j+1]=-Vi[k]*Ypm[k,k]*sin(gam)
hes[k+7,j+1]=2*Vi[k+1]*Ypm[k,k]*sin(Ypa[k])-Vi[k]*Ypm[k,k]*sin(bet)
hes[k+2,j+2]=2*cc[k]
hes[k+4,j+2]=-1./MVA
hes[k+6,j+3]=-1./MVA
hes[k,j+4]=-Vi[k]*Vi[k+1]*Ypm[k,k]*sin(gam)
hes[k+1,j+4]=-Vi[k]*Ypm[k,k]*cos(gam)
hes[k+2,j+4]=-1./MVA
hes[k,j+5]=-Vi[k]*Vi[k+1]*Ypm[k,k]*sin(bet)
hes[k+1,j+5]=2*Vi[k+1]*Ypm[k,k]*cos(Ypa[k])-Vi[k]*Ypm[k,k]*cos(bet)
hes[k,j+6]=-Vi[k]*Vi[k+1]*Ypm[k,k]*cos(gam)
hes[k+1,j+6]=-Vi[k]*Ypm[k,k]*sin(gam)
hes[k+3,j+6]=-1./MVA
hes[k,j+7]=Vi[k]*Vi[k+1]*Ypm[k,k]*cos(bet)
hes[k+1,j+7]=2*Vi[k+1]*Ypm[k,k]*sin(Ypa[k])-Vi[k]*Ypm[k,k]*sin(bet)
hesin=inv(hes)
hesin=matrix(hesin,(dx,dx))
deltax= mul(hesin*grad)
hesin=spmatrix([],[],[],(dx,dx))
hes=matrix(0,(dx,dx),tc='d')
for k in range(0,dx):
xnueva[k]=y[k]-deltax[k]
for k in range(0,dx):
if k==0:
angi[k+1]=xnueva[k]
y[k]=xnueva[k]
if k==1:
Vi[k]=xnueva[k]
y[k]=xnueva[k]
if k==2:
prgene[k-2]=xnueva[k]
14
B-14
y[k]=xnueva[k]
if k==3:
preacgene[k-3]=xnueva[k]
y[k]=xnueva[k]
if k==4 or k==5:
lam[k-4]=xnueva[k]
y[k]=xnueva[k]
if k==6 or k==7:
lr[k-6]=xnueva[k]
y[k]=xnueva[k]
dip=max(abs(deltax))
diq=max(abs(deltax))
it+=1
#print it
for k in range(0,nnbus):
anges[k]=angi[k]
cost=0
for k in range(0,2):
cost=cost+cf[k]+cv[k]*prgene[k]+cc[k]*prgene[k]**2
for k in range(0,2*nnbus):
if k<nnbus:
lamdas[k]=lam[k]
if k>=nnbus:
lamdas[k]=lr[k-nnbus]
fprlin=spmatrix([],[],[],(nbr,1),tc='d')
fpreaclin=spmatrix([],[],[],(nbr,1),tc='d')
#calculo flujos de potencia real en lineas
for k in range(0,nbr):
i=int(nl[k])-1
j=int(nr[k])-1
fprlin[k]=-Vi[i]**2*Ypm[i,j]*cos(Ypa[i,j])+Vi[i]*Vi[j]*Ypm[i,j]*cos(Ypa[i,j]+anges[j]-anges[i])
fpreaclin[k]=-Vi[i]**2*Ypm[i,j]*sin(Ypa[i,j])+Vi[i]*Vi[j]*Ypm[i,j]*sin(Ypa[i,j]+anges[j]-anges[i])
15
B-15
angesgr=spmatrix([],[],[],(nnbus,1))
for i in range(0,nnbus):
angesgr[i]=angi[i]*180/pi
f = open('reporteOPFAC'+str(nnbus)+'buses.txt', 'w')
format = "%.3f"
# imprimiendo voltajes de nodo
f.write('Magnitud de voltaje\n')
f.write('Bus pu\n')
for k in range(0,nnbus):
f.write(str(k+1)+' '+format %Vi[k]+'\n')
#print 'Magnitud de voltaje en pu'
#print Vi
# imprimiendo angulos de nodo
f.write('\n')
f.write('Angulo\n')
f.write('Bus grados\n')
for k in range(0,nnbus):
f.write(str(k+1)+' '+format %angesgr[k]+'\n')
#print 'Angulo en grados'
#print angesgr
# imprimiendo flujo potencia activa en las lineas
f.write('\n')
f.write('Potencia activa en lineas MW\n')
f.write('De hasta\n')
#print 'Potencia real en MW'
for k in range(0,nbr):
i=int(nl[k])-1
j=int(nr[k])-1
fprlin[k]=fprlin[k]*MVA
f.write(str(i+1)+' '+str(j+1)+' ')
f.write(format %fprlin[k]+'\n')
#print 'Flujo en lineas en MW'
#print fprlin
# imprimiendo flujo potencia reactiva en las lineas
f.write('\n')
f.write('Potencia reactiva en lineas MVAR\n')
f.write('De hasta\n')
16
B-16
#print 'Potencia real en MW'
for k in range(0,nbr):
i=int(nl[k])-1
j=int(nr[k])-1
fpreaclin[k]=fpreaclin[k]*MVA
f.write(str(i+1)+' '+str(j+1)+' ')
f.write(format %fpreaclin[k]+'\n')
#print 'Flujo en lineas en MVAR'
#print fpreaclin
# imprimiendo potencia activa generada NODAL
f.write('\n')
f.write('Potencia activa generada en MW\n')
f.write('Bus\n')
for k in range(0,nnbus):
f.write(str(k+1)+' ')
f.write(format %prgene[k]+'\n')
#print 'Potencia activa generada en MW'
#print prgene
# imprimiendo potencia reactiva generada NODAL
f.write('\n')
f.write('Potencia reactiva generada en MVAR\n')
f.write('Bus\n')
for k in range(0,nnbus):
f.write(str(k+1)+' ')
f.write(format %preacgene[k]+'\n')
#print 'Potencia reactiva generada en MVAR'
#print preacgene
#imprimiendo costos NODALES por POTENCIA ACTIVA
f.write('\n')
f.write('Costo marginal $/MWh\n')
f.write('Bus\n')
for k in range(0,nnbus):
f.write(str(k+1)+' ')
lamdas[k]=lamdas[k]/MVA
f.write(format %lamdas[k]+'\n')
#print 'Costo marginal $/MWh'
#for k in range(0,nnbus):
17
B-17
#print format %lamdas[k]
#print
#imprimiendo costos NODALES por REACTIVOS
f.write('\n')
f.write('Costo marginal $/MVARh\n')
f.write('Bus\n')
for k in range(nnbus,2*nnbus):
f.write(str(k+1-nnbus)+' ')
lamdas[k]=lamdas[k]/MVA
f.write(format %lamdas[k]+'\n')
#print 'Costo marginal $/MVARh'
#for k in range(nnbus,2*nnbus):
#print format %lamdas[k]
f.write('\n')
#imprimiendo costo TOTAL
f.write('Costo Total=$'+format %cost)
#print
#print "Costo Total=\n","$",format %cost,"\n"
return angesgr
f.close()
def apertura():
import os
print 'Abriendo reporte.....'
archivo=os.popen('reporteOPFAC'+str(nnbus)+'buses.txt')
18
B-18
ANEXO C
PROGRAMA DE FLUJO ÓPTIMO DE POTENCIA (OPF)
MODELO DC
1
from cvxopt import matrix, spmatrix, mul, div, sparse
from math import atan, sin, cos, pi
from scipy.linalg import inv
from scipy import conjugate
def carga():#definiendo la funcion para cargar los datos del archivo de datos
f = open('dc3.txt', 'r');
lines = f.readlines();
f.close()
global MVA
#leyendo MVA base del archivo
MVAB=lines[2].split()
MVA=int(MVAB[0])
#leyendo parametros de buses
ynames = lines[5].split()
y = {}
for name in ynames:
y[name] = []
s=0
while s<1:
for line in lines[6:]:
yvalues = [float(yi) for yi in line.split()]
if len(yvalues) == 0:
break
for name, value in zip(ynames, yvalues):
y[name].append(value)
s+=1
#leyendo parametros de linea
ul=8+len(y[name])
ul1=ul+1
ynames1 = lines[ul].split()
y1 = {}
for name1 in ynames1:
y1[name1] = []
d=0
while d<1:
for line in lines[ul1:]:
yvalues1 = [float(yi) for yi in line.split()]
1
C-1
if len(yvalues1) == 0:
break
for name1, value1 in zip(ynames1, yvalues1):
y1[name1].append(value1)
d+=1
2
C-2
#calculando potencias limites en p.u
for i in range(0,nnbus):
lip[i]=lip[i]/MVA
lsp[i]=lsp[i]/MVA
lipr[i]=lipr[i]/MVA
lspr[i]=lspr[i]/MVA
#potencias en p.u
pes=spmatrix([],[],[],(nnbus,1))
qes=spmatrix([],[],[],(nnbus,1))
for i in range(0,nnbus): # generando los valores de potencia en p.u
pes[i]=(prgene[i]-prload[i])/MVA
qes[i]=(preacgene[i]-preacload[i])/MVA
lini=spmatrix([],[],[],(nnbus,1),tc='d')
ppcal=spmatrix([],[],[],(nnbus,1),tc='d')
Vi=spmatrix([],[],[],(nnbus-1,1),tc='d')
angi=spmatrix([],[],[],(nnbus-1,1),tc='d')
bgene=0
for i in range(0,nnbus):
if i>0:
Vi[i-1]=V[i]#voltaje inicial
angi[i-1]=anges[i]#angulo inicial
if cv[i]>0:
bgene+=1
dx=bgene+2*nnbus-1
busgene=spmatrix([],[],[],(bgene,1))
dlpg=spmatrix([],[],[],(nnbus,1))
dlt=spmatrix([],[],[],(nbr1,1))
dll=spmatrix([],[],[],(nnbus,1))
busl=spmatrix([],[],[],(nnbus-bgene,1))
hes=matrix(0,(dx,dx),tc='d')
3
C-3
hesin=spmatrix([],[],[],(dx,dx))
grad=spmatrix([],[],[],(dx,1))
pig=spmatrix([],[],[],(bgene,1))
xn=spmatrix([],[],[],(dx,1),tc='d')
CV=spmatrix([],[],[],(bgene,1))
CC=spmatrix([],[],[],(bgene,1))
LAM=spmatrix([],[],[],(bgene,1))
a=0
for i in range(0,nnbus):
if cv[i]>0:
busgene[a]=nombus[i]
a+=1
b=0
for i in range(0,nnbus):
if cv[i]==0:
busl[b]=nombus[i]
b+=1
c=0
for i in range(0,nnbus):
lini[i]=lam[i]
if cv[i]>0:
pig[c]=prgene[int(busgene[c])-1]
CV[c]=cv[int(busgene[c])-1]
CC[c]=cc[int(busgene[c])-1]
c+=1
dpr=spmatrix([],[],[],(bgene,1),tc='d')
dtas=spmatrix([],[],[],(nnbus-1,1),tc='d')
dlam=spmatrix([],[],[],(nnbus,1),tc='d')
Y=spmatrix([],[],[],(nnbus,nnbus),tc='d')
y=matrix(1,(nbr1,1))
x1=spmatrix([],[],[],(nbr1,1))
y1=spmatrix([],[],[],(nbr1,1))
ds=div(y,x)
# Ybus fuera de la diagonal
for d in range(0,nbr1):
4
C-4
if nl1[d] > 0 and nr1[d] > 0:
x0=int(nl1[d])-1
y0=int(nr1[d])-1
Y[x0,y0]=Y[x0,y0]-ds[d]
Y[y0,x0]=Y[x0,y0]
# Ybus en la diagonal
for n in range(0,nnbus):
for k in range(0,nbr1):
x1[k]=int(nl1[k])-1
y1[k]=int(nr1[k])-1
if x1[k]==n:
Y[n,n]=Y[n,n]+ ds[k]
if y1[k]==n:
Y[n,n]=Y[n,n]+ ds[k]
for i in range(1,nnbus):
for j in range(0,nnbus):
Y1[i-1,j]=Y[i,j]
for i in range(0,nnbus):
for j in range(1,nnbus):
Y2[i,j-1]=Y[i,j]
5
C-5
hes0=matrix([MCC,MZERO3,MIMVA])
hes1=matrix([MZERO1,MZERO2,Y2])
hes2=matrix([MIMVA,Y1,MZERO])
hes5=matrix([[MCC],[MZERO1],[MIMVA]])
hes8=matrix([[hes0],[hes1],[hes2]])
for i in range(0,bgene):
for j in range(0,3*nnbus-1):
k=int(busgene[i])-1
hes3[j,i]=hes0[j,k]
hes4=matrix([[hes3],[hes1],[hes2]])
for i in range(0,bgene):
for j in range(0,dx):
k=int(busgene[i])-1
hes[i,j]=hes4[k,j]
nbng=nnbus-bgene
for i in range(bgene,dx):
for j in range(0,dx):
hes[i,j]=hes4[i+nbng,j]
hesin=inv(hes)
hesinv=matrix(hesin,(dx,dx))
C-6
6
#Generando la matriz GRADIENTE
xv=sparse([pig,angi,lam])# matriz de incognitas iniciales
admsum=spmatrix([],[],[],(nnbus,1),tc='d')
rangi=spmatrix([],[],[],(nnbus,nnbus),tc='d')
rang=spmatrix([],[],[],(nnbus,1),tc='d')
for i in range(0,bgene):
dpr[i]=CV[i]+2*CC[i]*pig[i]-LAM[i]/MVA
for i in range(0,nnbus):
for j in range(0,nnbus):
admsum[i]=admsum[i]+lam[j]*Y[i,j]
for i in range(1,nnbus):
dtas[i-1]=admsum[i]
#obteniendo derivadas respecto a lamdas
# Resta de Angulos fuera de la diagonal
for d in range(0,nbr1):
if nl1[d] > 0 and nr1[d] > 0:
x0=int(nl1[d])-1
y0=int(nr1[d])-1
rangi[x0,y0]=rangi[x0,y0]+anges[x0]-anges[y0]
rangi[y0,x0]=-rangi[x0,y0]
drl=mul(rangi,Y)
for i in range(0,nnbus):
for j in range(0,nnbus):
rang[i]=rang[i]-drl[i,j]
for i in range(0,nnbus):
dlam[i]=prload[i]/MVA-prgene[i]/MVA+rang[i]
grad=matrix([dpr,dtas,dlam])
deltax= mul(hesinv*grad)
for k in range(0,dx):
xn[k]=xv[k]-deltax[k]
for k in range(0,bgene):
7
C-7
pig[k]=xn[k]
for k in range(0,nnbus-1):
angi[k]=xn[k+bgene]
for k in range(0,nnbus):
lam[k]=xn[k+bgene+nnbus-1]
for i in range(0,bgene):
k=int(busgene[i])-1
LAM[i]=lam[k]
for k in range(1,nnbus):
anges[k]=angi[k-1]
for i in range(0,bgene):
k=int(busgene[i])-1
prgene[k]=pig[i]
dip=max(abs(deltax))
diq=max(abs(deltax))
it+=1
cost=0
for k in range(0,nnbus):
cost=cost+cf[k]+cv[k]*prgene[k]+cc[k]*prgene[k]**2
fplin=spmatrix([],[],[],(nbr1,1),tc='d')
#calculo flujos de potencia real en lineas
for k in range(0,nbr1):
i=int(nl1[k])-1
j=int(nr1[k])-1
fplin[k]=(anges[i]-anges[j])*Y[i,j]*(-1)*MVA
8
C-8
f.write('Magnitud de voltaje\n')
f.write('Bus pu\n')
for k in range(0,nnbus):
f.write(str(k+1)+' '+format %V[k]+'\n')
#print 'Magnitud de voltaje en pu'
#print V
# imprimiendo angulos de nodo
f.write('\n')
f.write('Angulo\n')
f.write('Bus grados\n')
for k in range(0,nnbus):
f.write(str(k+1)+' '+format %angesgr[k]+'\n')
#print 'Angulo en grados'
#print angesgr
# imprimiendo flujo en las lineas
f.write('\n')
f.write('Potencia real en lineas MW\n')
f.write('De hasta\n')
#print 'Potencia real en MW'
for k in range(0,nbr1):
i=int(nl1[k])-1
j=int(nr1[k])-1
f.write(str(i+1)+' '+str(j+1)+' ')
f.write(format %fplin[k]+'\n')
#print 'Flujo en lineas en MW'
#print fplin
# imprimiendo pptencia generada NODAL
f.write('\n')
f.write('Potencia generada en MWh\n')
f.write('Bus\n')
for k in range(0,nnbus):
f.write(str(k+1)+' ')
f.write(format %prgene[k]+'\n')
#print 'Potencia generada en MWh'
#print prgene
#imprimiendo costos NODALES
f.write('\n')
9
C-9
f.write('Costo marginal $/MWh\n')
f.write('Bus\n')
for k in range(0,nnbus):
f.write(str(k+1)+' ')
lam[k]=lam[k]/MVA
f.write(format %lam[k]+'\n')
#print 'Costo marginal $/MWh'
#print lam
f.write('\n')
#imprimiendo costo TOTAL
f.write('Costo Total=$'+format %cost)
#print "Costo Total=\n","$",format %cost,"\n"
return angesgr
f.close()
def apertura():
import os
print 'Abriendo reporte.....'
archivo=os.popen('reporteOPF'+str(nnbus)+'buses.txt')
10
C-10