UNIVERSIDAD CENTROAMERICANA “JOSÉ SIMEÓN CAÑAS” MODELO DE FLUJO ÓPTIMO DE POTENCIA UTILIZANDO TECNICAS DE OPTIMIZACIÓN TRABAJO DE GRADUACIÓN PREPARADO PARA LA FACULTAD DE INGENIERÍA Y ARQUITECTURA PARA OPTAR AL GRADO DE 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 ANDREU OLIVA DE LA ESPERANZA, S.J. SECRETARIA GENERAL CELINA PÉREZ RIVERA DECANO DE LA FACULTAD DE INGENIERÍA Y ARQUITECTURA CARLOS GONZALO CAÑAS GUTIÉRREZ COORDINADOR DE LA CARRERA DE INGENIERÍA ELÉCTRICA OSCAR ANTONIO VALENCIA MONTERROSA DIRECTOR DEL TRABAJO RIGOBERTO CONTRERAS VÁSQUEZ 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. Un sistema eléctrico de potencia (SEP), es el conjunto de centrales generadoras, de líneas de transmisión interconectadas mediante centros de transformación (subestaciones) y redes de distribución esenciales para el suministro de energía eléctrica. 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. Una función objetivo puede incorporar aspectos económicos, de seguridad o medioambientales, que se resuelve utilizando técnicas de optimización adecuadas. Las restricciones son leyes físicas que gobiernan a los generadores, el sistema de transmisión, límites constructivos de los equipos eléctricos y estrategias operativas. i ii ÍNDICE RESUMEN EJECUTIVO .......................................................................................................................i ÍNDICE DE FIGURAS ..........................................................................................................................v PRÓLOGO ......................................................................................................................................... vii CAPITULO 1. MODELADO DE LOS ELEMENTOS DEL SISTEMA DE POTENCIA ........................ 1 1.1 Modelado de líneas de transmision .......................................................................................... 1 1.1.1 CIircuitos equivalentes de líneas de transmision ............................................................... 2 1.2 Modelado de los transformadores............................................................................................. 5 1.2.1 Circuitos equivalentes por unidad de transformadores trifásicos balanceados de dos devanados ................................................................................................................................... 6 1.2.2 Transformadores de tres devanados ................................................................................. 7 CAPITULO 2. FLUJOS DE POTENCIA .............................................................................................. 9 2.1 Introduccion ............................................................................................................................... 9 2.2 Metodo de Newton-Raphson .................................................................................................. 10 2.3 El problema de flujo de potencia ............................................................................................. 13 2.4 Solucion de flujos de potencia por el método de Newton-Raphson ....................................... 15 CAPITULO 3. PROGRAMA DE FLUJOS DE POTENCIA ................................................................ 19 3.1 Mosulos de programación en PYTHON .................................................................................. 20 3.2 Modulo de Carga .................................................................................................................... 21 3.3 Modulo de ybus ...................................................................................................................... 22 3.4 Modulo Newton ....................................................................................................................... 23 3.5 Modulo fpotencia ..................................................................................................................... 25 3.6 Modulo salida .......................................................................................................................... 26 3.7 Ejemplo de flujo de potencia .................................................................................................. 27 3.8 Flujo de potencia en un sistema de catorce nodos................................................................. 32 CAPITULO 4. FLUJO ÓPTIMO DE POTENCIA ............................................................................... 35 4.1 Introduccion ............................................................................................................................. 35 4.2 El problema de flujo optimo de potencia ................................................................................. 36 4.2.1 Formulacion general ........................................................................................................ 36 4.2.2 Variables .......................................................................................................................... 37 4.2.3 Funcion objetivo ............................................................................................................... 38 4.2.4 Restricciones de igualdad ................................................................................................ 39 4.2.5 Restricciones de desigualdad .......................................................................................... 39 4.3 Casos de flujo optimo de potencia (OPF). .............................................................................. 41 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 CAPITULO 5. CONCLUSIONES Y RECOMENDACIONES ............................................................. 55 5.1 Conclusiones ........................................................................................................................... 55 5.2 Recomendaciones ................................................................................................................... 55 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 Figura 1.1 Modelo línea corta ............................................................................................................. 1 Figura 1.2 Modelo línea media ............................................................................................................ 1 Figura 1.3 Modelo línea larga ............................................................................................................. 2 Figura 1.4 Modelo nominal .............................................................................................................. 2 Figura 1.5 Modelo equivalente......................................................................................................... 4 Figura 1.6 (a) Transformador Ideal Estrella-Estrella ........................................................................... 6 Figura 1.7 Modelos de transformadores ............................................................................................. 7 Figura 2.1 Representación grafica .................................................................................................... 11 Figura 2.2 Variables del bus ............................................................................................................. 13 Figura 2.3 Bus típico de un sistema de potencia .............................................................................. 15 Figura 3.1 Diagrama unifilar (impedancias en pu, en 100MVA base) .............................................. 27 Figura 3.2 Diagrama de Flujo de Potencia. ...................................................................................... 31 Figura 3.3 Sistema de 14 Buses ....................................................................................................... 32 Figura 3.4 Interfaz del programa ....................................................................................................... 33 Figura 4.1 Variables de control y de estado ..................................................................................... 37 Figura 4.2 Diagrama unifilar de sistema de dos nodos..................................................................... 41 Figura 4.3 Hessiano sistema de dos nodos ...................................................................................... 44 Figura 4.4 Diagrama Unifilar con flujos en las líneas y costos marginales AC ................................ 46 Figura 4.5 Diagrama Unifilar de sistema de cuatro nodos ................................................................ 47 Figura 4.6 Hessiano sistema de cuatro buses .................................................................................. 51 Figura 4.7 Diagrama Unifilar con flujos en las líneas y sus costos marginales DC .......................... 53 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: Para la aplicación de cualquier método para la solución de un flujo de carga, requiere un conocimiento detallado de los elementos que componen un sistema de potencia. En este sentido el capitulo 1 presenta una revisión a los componentes o elementos que se tomaran en cuenta para el análisis del flujo de potencia, presentando como se modela cada uno de estos componentes. En el capitulo 2, se presenta el método de solución para el flujo de carga, detallando el método de una forma general y grafica para la comprensión de este. Se plantea también el problema del flujo de potencia el cual es calcular la magnitud del voltaje y el ángulo de fase en cada uno de los buses del sistema. Al final del capitulo se presenta la solución del flujo de potencia por el método de Newton-Raphson. 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. 1.1 Modelado de líneas de transmision 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. Figura 1.1 Modelo línea corta 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. Figura 1.2 Modelo línea media 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 1.1.1 CIircuitos equivalentes de líneas de transmision CIRCUITO NOMINAL A continuación se presenta el modelaje del circuito equivalente Figura 1.4 Modelo de una línea de transmisión nominal Por KCL la corriente en la impedancia en serie es designado por la es: Ec.1.1 La corriente en el extremo receptor es: Ec.1.2 Por LVK el voltaje en el extremo transmisor es: Ec.1.3 Donde: Por tanto, si Ec.1.4 es la tensión en el extremo emisor y la tensión en el extremo receptor, se tiene las siguientes relaciones: Ec .1.5 La corriente en el extremo del transmisor será: 2 Ec.1.6 Sustituyendo en se tiene: Ec.1.7 Donde: Ec.1.8 Ec.1.9 Ec.1.10 A las constantes ABCD se les llama constantes generalizadas de circuito de la línea de transmisión. En general, son números complejos, A y D son adimensionales e iguales entre sí, si la línea es la misma cuando se ve desde cada terminal. Las dimensiones de B y C son los ohmios y los mhos o siemens, respectivamente. Las constantes se aplican a cualquier red lineal, pasiva y con cuatro terminales en dos lados, y cada uno tiene un par de ellas. A tal circuito se le conoce como red de dos puertos. Se puede dar un significado físico a las constantes, así: Cuando , La constante B es la relación es cero se observa que A es la relación sin carga. cuando el extremo receptor esta en corto circuito. La constante A es útil en el cálculo de la regulación. Si es el voltaje en el extremo receptor a plena carga para un voltaje en el extremo generador la ecuación será: Por ciento de regulación: Ec.1.11 3 CIRCUITO EQUIVALENTE El circuito que se muestra en la figura 1.5 se llama circuito al circuito nominal excepto en que se usan ´ tales que el circuito en lugar de Z y Y. El objetivo es determinar y equivalente tenga los mismos parámetros ABCD que los de la línea distribuida. Los parámetros ABCD del circuito el circuito y equivalente. Es idéntico en estructura equivalente, el cual tiene la misma estructura que nominal, son: Ec.1.12 Ec.1.13 Ec.1.14 Figura 1.5 Modelo equivalente Ec.1.15 Ec.1.16 En donde se ha reemplazado Z y Y con Z´y Y´ al igualar las ecuaciones con Ec.1.13 Ec.1.17 Al escribir de nuevo la ecuación (1.17) en términos de la impedancia del circuito nominal, Ec.1.18 En donde por unidad De modo similar, igualando la ecuación (1.1.12) con 4 Ec.1.19 por unidad, Ec.1.20 Usando la ecuación (1.1.17) y la identidad , la ecuación (1.1.20) queda Ec.1.21 Al escribir de nuevo la ecuación (1.1.21) en términos de la admitancia del circuito nominal, Ec.1.22 En donde por unidad Las ecuaciones (1.1.19) y (1.1.23) dan los factores de corrección el circuito nominal, en Z´ y Y´ para el circuito Ec.1.23 y para convertir Z y Y, para 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. 1.2 Modelado de los transformadores 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. El modelo de transformador, incluye además el efecto de transformación de tensión debida al tap. Los transformadores poseen la capacidad de cambiar su razón de transformación a través de los taps, lo cual fue modelado como variable de control en el OPF. 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. 1.2.1 Circuitos equivalentes por unidad de transformadores trifásicos balanceados de dos devanados La figura 1.6(a) es una representación de un transformador ideal estrella-estrella, conectado a tierra a través de las impedancias y del neutro. 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: 1. Se selecciona una común tanto para la terminal H como para la X. 2. Se selecciona la relación de transformación respecto a las tensiones bases, , para que sea igual a la relación de las tensiones nominales línea a línea, . Figura 1.6 (a) Transformador Ideal Estrella-Estrella Figura 1.6 (b) Circuito equivalente por unidad Cuando se aplican corrientes trifásicas balanceadas al transformador, las corrientes en el neutro son igual a cero y no se tienen caídas de tensión a través de las impedancias de neutro. 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, tienen sus polaridades e salen por las terminales con punto, y , y 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. Figura 1.7 Modelos de transformadores Las ramas de admitancia en derivación, un resistor de pérdidas en el núcleo en paralelo con un inductor magnetizado, se puede evaluar a partir de una prueba de circuito abierto. Asimismo, cuando un devanado se deja abierto, el transformador de tres devanados se comporta como uno de dos devanados y se pueden aplicar las pruebas estándar de cortocircuito para evaluar las impedancias de dispersión por unidad, las cuales se definen como sigue: 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. De la figura 1.6 (c), con el devanado 2 en cortocircuito y el 3 abierto, la impedancia de dispersión medida del devanado 1 es, despreciando la rama de admitancia en derivación, Ec.1.28 De igual modo, Ec.1.29 y Ec.1.30 Resolviendo las ecuaciones anteriores, Ec.1.31 Ec.1.32 Ec.1.33 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 ecuaciones. 8 común, antes de que se usen en las 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: Problema de flujo carga Problema de programación optima de carga Problema de control de sistemas 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 El método de Newton-Raphson es un método para resolver ecuaciones algebraicas no lineales. Funciona más rápidamente y es seguro que converge en la mayor parte de los casos al compararlo con otros métodos. Es sin duda el método práctico para la solución de flujo de carga en redes eléctricas de potencia grandes. 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. Considere un sistema de n ecuaciones algebraicas no lineales ; Suponga que los valores iniciales de las incógnitas son Ec.2.1 Sean las correcciones que, al hacerse a la primera suposición, dan la solución real. Por lo tanto, Ec.2.2 Al desarrollar estas ecuaciones en serie de Taylor con la suposición inicial, se tiene Donde son las derivadas de con respecto a , evaluadas en Si los términos de orden superior se desprecian, puede escribirse en forma matricial Ec.2.3 O en forma de matriz vectorial Ec.2.4 se conoce como matriz jacobiana (que se obtiene al diferenciar el vector función respecto a y se evalúa en con ). 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. Los valores actualizados de son entonces O, en general, para la iteración , 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. Supongamos una función a la que se desea calcular su raíz Figura 2.1 Representación grafica 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 Para encontrar el valor de que es mucho más cercano a la raíz que , se tomara la ecuación de la recta. 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 Si buscamos una mejor aproximación a la raíz utilizando este nuevo valor Ec.2.11 Si nuevamente se busca otra aproximación que es cada vez más cercana a la raíz, Ec.2.12 Entonces podemos generalizar la ecuación de la siguiente manera, 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. También observe que en el caso de que , el método no se puede aplicar. De hecho, vemos geométricamente que esto significa que la recta tangente es horizontal y por lo tanto no intercepta al eje raíz de en ningún punto, a menos que coincida con éste, en cuyo caso . 12 mismo es una 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 Carga L G Figura 2.2 Variables del bus 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 Cada bus en la figura 2.2 se separa en generación y carga. Es decir, se clasifica en uno de los tres tipos siguientes: 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 13 , por lo común 1.0 y por unidad, es un dato de entrada. El programa de flujo de potencia calcula . 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: calcula y y son datos de entrada. El programa de flujo de potencia . 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. Observe que cuando el bus k es un bus de carga sin ninguna generación, es negativo; es decir que la potencia real suministrada al bus k en la figura 2.2 es negativa. Si la carga es inductiva, es negativa. 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 derivación del circuito y la admitancia de 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 excitación por unidad , la admitancia de la rama de , los buses a los que están conectados los devanados y las capacidades máximas en MVA. La matriz de admitancia de se puede construir a partir de los datos de entrada de transformadores y líneas. Los elementos de Elementos de la diagonal: son: es igual a la suma algebraica de todas las admitancias que terminan en el nodo. Elementos fuera de la diagonal: Es igual al negativo de la suma de todas las admitancias conectadas directamente entre estos dos nodos. Además, 14 2.4 Solucion de flujos de potencia por el método de Newton-Raphson Debido a su convergencia cuadrática, el método de Newton es matemáticamente superior al método de Gauss-Seidel y es menos propenso a la divergencia con problemas mal condicionados. 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 Figura 2.3 Bus típico de un sistema de potencia 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 La potencia compleja en el bus i es Ec.2.17 Sustituyendo la ecuación (2.13) en (2.14) Ec.2.18 15 Separando la parte real e imaginaria Ec.2.19 Ec.2.20 Las ecuaciones (2.19) y (2.20) constituyen un grupo de ecuaciones algebraicas no lineales en términos de variables independientes, la magnitud del voltaje en por unidad, y el ángulo de fase en radianes. Tenemos dos ecuaciones por cada bus de carga, dadas por (2.19) y (2.20), y una ecuación por cada bus de controlador de voltaje dada por (2.19). Expandiendo (2.19) y (2.20) en serie de Taylor sobre la estimación inicial y dejando de lado los términos de orden superior da como resultado el siguiente conjunto de ecuaciones lineales. 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 voltaje y la magnitud del con los cambios pequeños en la potencia real y reactiva y . Los elementos de la matriz jacobiana son las derivadas parciales de (2.19) y (2.20), evaluados en y . En una forma corta esta se puede escribir como 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 de potencia real y restricciones de potencia reactiva, y la matriz Jacobiana es de orden . El . El es de orden restricciones es de orden . El , y el La diagonal y los elementos fuera de la diagonal de 16 es de orden son es de orden . Ec.2.22 Ec.2.23 La diagonal y los elementos fuera de la diagonal de son Ec.2.24 Ec.2.25 La diagonal y los elementos fuera de la diagonal de son Ec.2.26 Ec.2.27 La diagonal y los elementos fuera de la diagonal de son 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: 1. Para el bus de carga, donde y son especificados, la magnitud del voltaje y el ángulo de fase son valores iguales al del bus slack, o 1.0, los buses regulado por voltaje, donde y y . Para son especificados, el ángulo de fase es igual al ángulo de fase del bus slack, o 0, 2. Para el bus de carga, y . son calculados con (2.19) y (2.20) y y son calculados con (2.30) y (2.31) respectivamente. 3. Para el bus controlado por voltaje, y 4. Los elementos de la matriz Jacobiana son calculados con (2.19) y (2.30). y son calculados con (2.22)-(2.29). 5. La nueva magnitud de voltaje y ángulo de fase son calculados por (2.32) y (2.33). 6. El proceso se continua hasta que los residuos especificada 17 y son menores que la precisión 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: La generación abastece la demanda (carga) más las perdidas. Las magnitudes de voltaje en las barras permanecen cercanas a sus valores nominales Los generadores operan dentro de limites especificados de potencia real y reactiva Las líneas de transmisión y los transformadores no están sobrecargados. El programa de computadora de flujos de potencia (conocidos como flujos de carga) es la herramienta básica para investigar estos requerimientos. Con este programa se calcula la magnitud del voltaje y el ángulo en cada barra o bus en un sistema de potencia en condiciones balanceadas en estado trifásico. También permite calcular los flujos de potencia real y reactiva para los equipos que interconectan las barras, así como las perdidas en los equipos. 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. Se realizara todo el código de programación en lenguaje Python, el programa se desarrollara de una forma modular para una mayor comprensión, y se explicara en que consiste cada uno de estos módulos. 19 3.1 Módulos de programación en PYTHON El programa de flujo de potencia desarrollado consta de los siguientes módulos: 1. Modulo de Carga de datos. Es el encargado de la lectura de datos. 2. Modulo Ybus. Se formara la matriz de admitancia. 3. Modulo Newton. Resuelve el problema de flujo de carga por el método de NewtonRaphson. 4. Modulo fpotencia. Calcula los flujos de potencia activa y reactiva. 5. Modulo Salida. Muestra los resultados obtenidos. 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. En el siguiente bloque de la interfaz se encuentran la interconexión de los buses y los parámetros de la línea que los interconecta siendo dichos parámetros resistencia (R), reactancia (X) y susceptancia (B). Después se encuentra el bloque en donde se especifica la interconexión de las líneas en paralelo del sistema con sus parámetros respectivos. En el bloque siguiente se encuentran los datos de transformadores de dos devanados en el cual se introducen los parámetros de resistencia, reactancias y susceptancia. 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. A continuación se presenta un ejemplo de la interfaz del programa elaborado. 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 Este modulo o función genera la matriz de admitancias conocida en el análisis de sistemas de potencia como YBUS. El código de este modulo se encuentra a continuación 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. La segunda de la etapas importantes de este modulo es la etapa de formación de la matriz Jacobiana la cual se divide en cuatro submatrices llamadas J1, J2, J3 y J4 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 Como subproducto de calculo iterativo de voltajes y ángulos utilizando el método de Newton se derivan los cálculos de flujos de potencia activa y reactiva en cada una de las líneas y elementos que existen en el sistema de potencia en análisis, y para ello el modulo fpotencia calcula estos flujos de potencia actica y reactiva a partir de los valores proporcionados por el método de Newton. 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. Con el objeto de demostrar la aplicación del programa diseñado se presenta a continuación ejemplos a distintos sistemas de potencia. 26 3.7 Ejemplo de flujo de potencia La solución de flujo de potencia por el método de Newton-Raphson es demostrado en el siguiente ejemplo: 1 Slack Bus 2 3 Figura 3.1 Diagrama unifilar (impedancias en pu, en 100MVA base) 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: Esto da lugar a la matriz de admitancia de bus Convirtiendo la matriz de admitancia de bus a forma polar con sus ángulos en radianes De (2.16) y (2.17), la expresión de la potencia real en el bus 2 y 3 y la potencia reactiva en el bus 2 son 27 Los elementos de la matriz Jacobiana son obtenidas por las derivadas parciales con respecto a y , . La carga y generación expresada en por unidad son El voltaje del bus slack es pu, y en el bus 3 la magnitud del voltaje es Iniciando con una estimación inicial de , ,y pu. , los residuos de potencia son calculados con (2.27) y (2.28) Evaluando los elementos de la matriz Jacobiana con la estimación inicial, el conjunto de ecuaciones lineales en la primera iteración se convierte en Obteniendo la solución de la ecuación de la matriz anterior, los nuevos voltajes de bus en la primera iteración son 28 El ángulo del voltaje de fase es en radianes. Para la segunda iteración, tenemos Y Para la tercera iteración, tenemos Y La solución converge en 3 iteraciones con un desfasamiento máximo de potencia de y con . De (2.17) y (2.18), las expresiones de la potencia reactiva en el bus 3 y las potencias real y reactiva en el bus slack son Tras la substitución, tenemos 29 Para encontrar los flujos en las líneas, primero se encuentran las corrientes de línea Los flujos en las líneas son Y las perdidas en las líneas son 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. 218.423 179.362 170.968 118.734 39.061 101.947 38.878 238.878 400 229.032 250 140.852 22.118 21.569 167.746 200 148.053 146.177 Flujo en MW Flujo en Mvar Figura 3.2 Diagrama de Flujo de Potencia. Comparando los resultados anteriores con los obtenidos con el programa desarrollado en Python, los resultados son exactamente los mismos. A continuación se presenta el reporte de salida que genera el programa. 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. Figura 3.3 Sistema de 14 Buses 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 Figura 3.4 Interfaz del programa 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. Dos objetivos básicos se deben cumplir en la operación de un sistema eléctrico de potencia: i) Asegurar una operación segura, y ii) Encontrar un punto de operación económico. 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. La aplicación de técnicas de optimización a los problemas de planificación y operación de SEP (Sistema Eléctrico de Potencia), como lo es OPF, es una activa área de investigación. De esta forma, OPF puede ser visto como un término genérico que describe una amplia gama de clases de problemas en los cuales se busca optimizar una función objetivo específico, sujeto a restricciones que representan los balances de potencia activa y reactiva en los nodos de la red, en función de las tensiones y ángulos de las barras. Existen variadas funciones objetivos que puede considerar un modelo OPF, entre las cuales se pueden mencionar (Ristanovic, 1996): Minimización de los costos por generación de potencia activa, · Minimización de pérdidas de potencia activa, · Minimización del cambio en las variables de control, · Minimización de la potencia no servida, etc. Una gran variedad de técnicas de optimización han sido aplicadas para resolver OPF (Momoh y ElHawary, 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. El presente trabajo se presentara dos casos de sistemas de potencia, el primero es un sistema compuesto por dos nodos y modelado AC el cual debido a su complejidad para su resolución y formulación general se opto por resolver el segundo caso el cual es un sistema multimodal y modelado DC. El análisis se hará sin restricciones de desigualdad; y solución por método de Newton-Raphson. Se abordaran el métodos antes mencionado para el modelamiento y resolución, considerando función objetivo que contempla la minimización de costos por generación de potencia activa. 4.2 El problema de flujo optimo de potencia Un estudio de flujos de potencia óptimo es utilizado ampliamente en la industria eléctrica para diferentes aplicaciones, que van desde estudios de planeación hasta operación de los sistemas. El principal objetivo de un OPF 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 . Una función objetivo puede incorporar aspectos económicos, de seguridad o medioambientales, que se resuelve utilizando técnicas de optimización adecuadas. Las restricciones son leyes físicas que gobiernan a los generadores, el sistema de transmisión, límites constructivos de los equipos eléctricos y estrategias operativas. Esta clase de problema es expresado como un problema de programación no lineal, con la función objetivo expresada como una función no lineal, y las restricciones expresadas como ecuaciones lineales y no lineales. 4.2.1 Formulacion general 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 Las variables de control y de estado a considerar en el OPF se resumen en la Figura 4.1. Se considera la simbología estándar utilizada en la literatura relacionada. G , Figura 4.1 Variables de control y de estado 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. El vector x contiene las variables de control y estado, incluye: : Potencia activa generador j: : Potencia reactiva generador j: : Voltaje en el bus i: 37 : Angulo de voltaje en el bus i: : Tap del transformador j: Siendo el conjunto de buses en la red eléctrica y , el conjunto de generadores y transformadores conectados a los buses (o nodos). El vector x entonces será: 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 4.2.3 Funcion objetivo La función objetivo representa el criterio (o índice de desempeño) usado para optimizar. La selección de la función objetivo obedece a un análisis cuidadoso de la seguridad y economía del sistema eléctrico de potencia. Algunas de las funciones objetivo empleadas en un estudio de OPF son: Minimizar el costo de generación. Minimizar las pérdidas de transmisión de potencia activa. Minimizar las pérdidas de transmisión de potencia reactiva. Minimizar el costo por interrupción de carga. Minimizar el número de reprogramación de los controles. Minimizar emisiones contaminantes por parte de los generadores térmicos. 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 Para un caso DC la ecuación a considerar es: Ec.4.9 Para un caso AC las ecuaciones a considerar son: Ec.4.10 Ec.4.11 4.2.5 Restricciones de desigualdad 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: Límites de potencia activa y reactiva de generación: La potencia activa y reactiva asignada a las unidades de generación deben estar dentro de límites de operación. Esta restricción refleja los límites operativos y térmicos que un generador debe satisfacer. Ec.4.12 Ec.4.13 39 Donde y son los limites de potencia activa mínima y máxima, respectivamente, para el i-esimo generador; y son los limites de potencia reactiva mínima y máxima, respectivamente para el i-esimo generador. 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: Donde representa la magnitud del voltaje en el i-esimo nodo de carga, magnitud de voltaje de referencia, en general definido como Otras restricciones que pueden ser incluidas en un OPF son: Límites del cambiador de fase de un transformador. Límites de las variables de control de los dispositivos FACTS. Límites de compensación de potencia reactiva. Requerimientos de reserva rodante. Límites de emisión de contaminantes al medio. 40 representa la 4.3 Casos de flujo optimo de potencia (OPF). A continuación se presentaran dos casos de sistemas de potencia a los cuales se analizaran y se desarrollaran aplicando todo lo antes mencionado además estos se resolverán en Python mostrando sus resultados. 4.3.1 OPF de un sistema de dos nodos y modelado AC: sin restricciones de desigualdad. Por método de Newton-Raphson A continuación plantearemos un ejemplo sencillo de un sistema de potencia compuesto por dos nodos y un generador. Dicho sistema se resolverá por medio de un análisis AC, en este caso si incluimos las potencias reactivas tanto generadas como las demandadas. 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. Figura 4.2 Diagrama unifilar de sistema de dos nodos 1. Planteamiento del problema Min Sujeto a: Balance nodal de potencia real: Balance de potencia reactiva: 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 Teniendo en cuenta que: Sabemos que: Análogamente tenemos: 2. Ecuación de LaGrange Planteando las condiciones de primer orden: 42 3. Método de Newton-Raphson Se procederá a resolverlo mediante el método de Newton-Raphson descrito en la sección 2.2. El método esta definido por. Donde es el vector de variables. 43 : Se conoce como el Hessiano, definido así: Para el caso en estudio el Hessiano queda definido como: En donde B es la matriz siguiente: Dejando claro que Figura 4.3 Hessiano sistema de dos nodos 44 Se procederá a resolver el problema mediante el programa elaborado en Python. Los datos del problema son los siguientes: La ecuación de costos de cada generador esta definida por: Reactancias: Introducimos los datos en nuestra interfaz: Al correr el programa los resultados son los siguientes Los resultados muestran el flujo de potencia activa y reactiva en MW y en MVAR respectivamente, en la línea, el flujo va del nodo 1 hacia el nodo 2. 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: : Es el costo de la energía activa, al incrementar un MWh de generación, para este caso es coincidente con el precio nodal de la demando (costo marginal de la demanda), al requerir un MWh adicional. : Es el costo de la energía activa al incrementar un MWh en la demanda en el nodo dos, observamos que el precio de la energía en este nodo es mayor que el precio en el nodo 1 debido principalmente a las pérdidas producidas por la impedancia de la línea. : Costo de la energía reactiva en el nodo de generación, para el caso es cero pues nuestro modelo esta basado en costos de generación activa y no reactiva. : Costo de la energía reactiva en el nodo de carga, en este caso es aproximadamente cero, pero no cero, debido a los costos de traslado y perdidas del sistema. A continuación se muestra el sistema con todos sus flujos y costos marginales. 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. Las consideraciones que se toman para un análisis DC son las siguientes: Se ignoran las perdidas de potencia activa Las diferencias de fase angular entre los nodos de cualquier rama son pequeños Se considera que las magnitudes de las tensiones de nodo son aproximadamente 1 p.u. Figura 4.5 Diagrama Unifilar de sistema de cuatro nodos La formulación del modelo DC de flujo de potencia se obtiene a partir de la modificación de la representación general del flujo de potencia AC, lo cual puede ser ilustrado en las siguientes ecuaciones: 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 entonces que también , De esta forma para todas las líneas. Esto implica para todas las líneas. Por lo tanto: Ec.4.17 Se asume que la diferencia de ángulos de fase es muy pequeña, entonces, pueden aproximarse de la siguiente manera: Ec.4.18 Ec.4.19 Las simplificaciones anteriores, cumplen con las características de las redes de transmisión y no conllevan a errores significativos en los resultados de la distribución de flujos de potencia activa. Cuando se agregan a la ecuación de potencia activa entonces el resultado es el siguiente: Ec.4.20 Entonces la ecuación de flujo de potencia en las líneas de transmisión queda definida de la siguiente manera: Ec.4.21 48 1. Planteamiento Se va a plantear el problema del OPF con el unifilar de la figura 4.5 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 Por lo tanto la ecuación a minimizar esta definida como: Min Ec.4.23 En donde estará sujeta a: Ecuaciones de balance nodal dadas por: 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 Planteamos la ecuación de LaGrange en función de cada una de las variables, así: 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 Se procederá a resolverlo mediante el método de Newton-Raphson descrito en la sección 2.2. El método esta definido por. Donde es el vector de variables. : Se conoce como el Hessiano, definido así: 50 Para el caso en estudio el Hessiano queda definido como: En donde A es la matriz siguiente 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 Figura 4.6 Hessiano sistema de cuatro buses Por lo tanto: 51 Se procederá a resolver el problema con le programa elaborado en Python. Los datos del problema son los siguientes: La ecuación de costos de cada generador esta definida por: Reactancias: Primero introducimos los datos del problema a nuestra interfaz 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 el programa de análisis de flujo de carga pudiéndose analizar SEP de gran tamaño y considerando el modelado de transformadores con tap, de dos y tres devanados, y el modelado de las líneas de transmisión. 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. En los programas desarrollados en el intérprete libre (PYTHON), se tomo como metodología de solución el método iterativo de NEWTON por ser este uno de los métodos más poderosos para resolver este tipo de problemas no lineales y uno de los más conocidos. 5.2 Recomendaciones Por parte del departamento de Ciencias Energéticas y Fluídicas, de la Universidad Centroamericana José Simeón Cañas, UCA, El Salvador, seguir ahondando en el presente tema de investigación, que constituye una poderosa herramienta de análisis para el Ingeniero Electricista, en el campo de los SEP. 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)) # parametros de las lineas 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 #parametros de lineas en paralelo nbr2=len(y2['nl1'])# numero de lineas en //del sistema nomlinp=matrix(y2['nlp'],(nbr2,1))#nombre de linea // nlp1=matrix(y2['nl1'],(nbr2,1))#linea desde nrp1=matrix(y2['nr1'],(nbr2,1))#linea hasta Rp=matrix(y2['R1'],(nbr2,1))# resitencia de linea xp=matrix(y2['X1'],(nbr2,1))#reactancia de linea Bp=matrix(y2['B1'],(nbr2,1))#suceptancia de linea lp=matrix(y2['a1'],(nbr2,1)) 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] #parametros 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 nrt2=matrix(y3['nr2t'],(nbr3,1))#hasta R2=matrix(y3['R2'],(nbr3,1))# resitencia x2=matrix(y3['X2'],(nbr3,1))#reactancia B2=matrix(y3['B2'],(nbr3,1))#susceptancia 6 A-6 A2=matrix(y3['a2'],(nbr3,1))#relacion de tranformacion #parametros de transformadores de 3 devanados nbr4=len(y4['nl3t'])# numero de transformadores de 3 devanados nomt3=matrix(y4['nomtransf3'],(nbr4,1))#nombre de transformador nlp2=matrix(y4['nl3t'],(nbr4,1))#desde np12=matrix(y4['nr3t1'],(nbr4,1))#hasta secundario np13=matrix(y4['nr3t2'],(nbr4,1))#hasta terciario rps=matrix(y4['R12'],(nbr4,1))# resitencia primario-secundario rpt=matrix(y4['R13'],(nbr4,1))# resitencia primario-terciario rst=matrix(y4['R23'],(nbr4,1))# resitencia secundario-terciario xps=matrix(y4['X12'],(nbr4,1))# reactancia primario-secundario xpt=matrix(y4['X13'],(nbr4,1))# reactancia primario-terciario xst=matrix(y4['X23'],(nbr4,1))# reactancia secundario-terciario bps=matrix(y4['B12'],(nbr4,1))# susceptancia primario-secundario bpt=matrix(y4['B13'],(nbr4,1))# susceptancia primario-terciario bst=matrix(y4['B23'],(nbr4,1))# susceptancia secundario-terciario A3=matrix(y4['a3'],(nbr4,1))#relacion de tranformacion nc=matrix(y4['nc'],(nbr4,1))#nodo comun del transformador de tres devanados x31=spmatrix([],[],[],(nbr4,1),tc='d') x32=spmatrix([],[],[],(nbr4,1),tc='d') x33=spmatrix([],[],[],(nbr4,1),tc='d') x12=spmatrix([],[],[],(nbr4,1),tc='d') x13=spmatrix([],[],[],(nbr4,1),tc='d') r31=spmatrix([],[],[],(nbr4,1),tc='d') r32=spmatrix([],[],[],(nbr4,1),tc='d') r33=spmatrix([],[],[],(nbr4,1),tc='d') r12=spmatrix([],[],[],(nbr4,1),tc='d') r13=spmatrix([],[],[],(nbr4,1),tc='d') b31=spmatrix([],[],[],(nbr4,1),tc='d') b32=spmatrix([],[],[],(nbr4,1),tc='d') b33=spmatrix([],[],[],(nbr4,1),tc='d') b12=spmatrix([],[],[],(nbr4,1),tc='d') b13=spmatrix([],[],[],(nbr4,1),tc='d') for k in range(0,nbr4): #reactancia x31[k]=0.5*(xps[k]+xpt[k]-xst[k]) 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) #calculo 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)) #generando los valores de potencia en p.u for i in range(0,nnbus): pes[i]=(prgene[i]-prload[i])/MVA qes[i]=(preacgene[i]-preacload[i])/MVA def ybus():# funcion que genera la matriz ybus global Ypa, Ypm, Y, bc,ds #matrices necesarias para generar la matriz de admitancias Ybus xc=spmatrix([],[],[],(nbr,1),tc='z') bc=spmatrix([],[],[],(nbr,1),tc='z') x1=spmatrix([],[],[],(nbr,1)) y1=spmatrix([],[],[],(nbr,1)) Y=spmatrix([],[],[],(nnbus,nnbus),tc='z') y=matrix(1,(nbr,1)) Ypr=spmatrix([],[],[],(nnbus,nnbus)) 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 #pasando Ybus de rectangular a polar for n in range(0,nnbus): 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 def newton():#funcion metodo de newton global jac, delta, pcal,qcal,iterac,dpi,dqi aas=spmatrix([],[],[],(nnbus,1)) bbs=spmatrix([],[],[],(nnbus,1)) ngs=spmatrix([],[],[],(nnbus,1)) nss=spmatrix([],[],[],(nnbus,1)) #declaracion de matrices y variables utilizadas it=0#numero de iteraciones er = 0.001 #tolerancia dip=5 diq=5 #inicio metodo de newton while (dip and diq) > er and it<=10: pcal=spmatrix([],[],[],(nnbus,1),tc='d') qcal=spmatrix([],[],[],(nnbus,1),tc='d') if it==0: tbuscam=matrix(1,(nnbus,1),tc='d') 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]) #primera consideracion de limites de potencia reactiva if it==0: for i in range(1,nnbus): if tbus[i]==2 or tbuscam[i]==0: if qcal[i]<lipr[i] and lipr[i]>0: qcal[i]=lipr[i] tbus[i]=0 tbuscam[i]=0 else: tbuscam[i]=1 #tbus[i]=2 if qcal[i]>lspr[i]: qcal[i]=lspr[i] tbus[i]=0 tbuscam[i]=0 else: tbuscam[i]=1 #tbus[i]=2 cbpvpq=0 for i in range(1,nnbus): if tbuscam[i]==0: cbpvpq+=1 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 #dimensiones submatrices jacobianas omj=2*nnbus-aa-2 omj1=nnbus-1 omj2=omj1-aa #matrices necesarias solo en la primera iteracion if it==0: jac=matrix(0,(omj,omj),tc='d') delta=matrix(0,(omj,1),tc='d') iterac=spmatrix([],[],[],(omj,1),tc='d') ite=matrix(0,(omj,1),tc='d') #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 #formando matriz de deltas for i in range(0,omj): if i<omj1: delta[i]=dpi[i] if i>=omj1: delta[i]=dqi[i-omj1] f=0 if it==0: for j in range(1,omj): if j<omj1: ite[j]=anges[j] if j>=omj1: ite[j]=V[int(pq[f])] 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 #pasando submatriz j1 a matriz jacobiana for i in range(0,omj1): for g in range(0,omj1): jac[i,g]=j1[i,g] #pasando submatriz j2 a matriz jacobiana for i in range(0,omj1): for g in range(0,omj2): jac[i,g+omj1]=j2[i,g] #pasando submatriz j3 a matriz jacobiana for i in range(omj1,omj): for g in range(0,omj1): jac[i,g]=j3[i-omj1,g] #pasando submatriz j4 a matriz jacobiana for i in range(omj1,omj): for g in range(0,omj2): jac[i,g+omj1]=j4[i-omj1,g] 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 return jac, V, anges def fpotencia():#funcion que calcula los flujos en las lineas global fp,fq,Ii,Ij,fqdi,fpdi,ppr, ppre fp=spmatrix([],[],[],(nbr,1)) fq=spmatrix([],[],[],(nbr,1)) fpdi=spmatrix([],[],[],(nbr,1)) fqdi=spmatrix([],[],[],(nbr,1)) ppr=spmatrix([],[],[],(nbr,1)) ppre=spmatrix([],[],[],(nbr,1)) Ii=spmatrix([],[],[],(nbr,1),tc='z') Ij=spmatrix([],[],[],(nbr,1),tc='z') sij=spmatrix([],[],[],(nbr,1),tc='z') sji=spmatrix([],[],[],(nbr,1),tc='z') Vc=spmatrix([],[],[],(1,nnbus),tc='z') 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 def salida():#funcion que genera el reporte de flujos global angesgr angesgr=spmatrix([],[],[],(nnbus,1)) for i in range(0,nnbus): angesgr[i]=anges[i]*180/pi f = open('reporte'+str(nnbus)+'buses.txt', 'w') format = "%.3f" 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 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 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 # imprimiendo flujo en las lineas f.write('\n') f.write('Potencia real MW\n') 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 %fpdi[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 #imprimiendo flujo en las lineas f.write('\n') f.write('Potencia reactiva MVAR\n') 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 #imprimiendo perdidas en las lineas f.write('\n') f.write('Perdidas potencia real MW\n') 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 %ppr[k]+'\n') #print #imprimiendo perdidas en las lineas f.write('\n') f.write('Perdidas potencia reactiva MVAR\n') 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 %ppre[k]+'\n') #print return angesgr f.close() 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 #generando matrices de datos global preacload,lr,preacgene,lam,prgene,prload,nbr4,nlt,nnbus,anges,tbus,V,nombus,pes,qes,nbr,nl,nr,R, x,lip,lsp,lipr,lspr,B,A,cf,cv,cc #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)) lr=matrix(y['lreac'],(nnbus,1)) cf=matrix(y['a'],(nnbus,1)) cv=matrix(y['b'],(nnbus,1)) 3 B-3 cc=matrix(y['c'],(nnbus,1)) lam=matrix(y['l'],(nnbus,1)) # parametros de las lineas nbr1=len(y1['nl'])# numero de líneas del sistema nomlin=matrix(y1['nomlin'],(nbr1,1))#nombre de línea nl1=matrix(y1['nl'],(nbr1,1))#línea desde nr1=matrix(y1['nr'],(nbr1,1))#línea hasta R1=matrix(y1['R'],(nbr1,1))# resistencia de línea x1=matrix(y1['X'],(nbr1,1))#reactancia de línea B1=matrix(y1['B'],(nbr1,1))#suceptancia de línea A1=matrix(y1['a'],(nbr1,1))#línea o transformador #parámetros de líneas en paralelo nbr2=len(y2['nl1'])# numero de líneas en //del sistema nomlinp=matrix(y2['nlp'],(nbr2,1))#nombre de línea // nlp1=matrix(y2['nl1'],(nbr2,1))#línea desde nrp1=matrix(y2['nr1'],(nbr2,1))#línea hasta Rp=matrix(y2['R1'],(nbr2,1))# resistencia de línea xp=matrix(y2['X1'],(nbr2,1))#reactancia de línea Bp=matrix(y2['B1'],(nbr2,1))#suceptancia de línea lp=matrix(y2['a1'],(nbr2,1)) 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 #parámetros de transformadores de 3 devanados nbr4=len(y4['nl3t'])# numero de transformadores de 3 devanados nomt3=matrix(y4['nomtransf3'],(nbr4,1))#nombre de transformador nlp2=matrix(y4['nl3t'],(nbr4,1))#desde np12=matrix(y4['nr3t1'],(nbr4,1))#hasta secundario np13=matrix(y4['nr3t2'],(nbr4,1))#hasta terciario rps=matrix(y4['R12'],(nbr4,1))# resistencia primario-secundario rpt=matrix(y4['R13'],(nbr4,1))# resistencia primario-terciario rst=matrix(y4['R23'],(nbr4,1))# resistencia secundario-terciario xps=matrix(y4['X12'],(nbr4,1))# reactancia primario-secundario xpt=matrix(y4['X13'],(nbr4,1))# reactancia primario-terciario xst=matrix(y4['X23'],(nbr4,1))# reactancia secundario-terciario bps=matrix(y4['B12'],(nbr4,1))# susceptancia primario-secundario bpt=matrix(y4['B13'],(nbr4,1))# susceptancia primario-terciario bst=matrix(y4['B23'],(nbr4,1))# susceptancia secundario-terciario A3=matrix(y4['a3'],(nbr4,1))#relación de transformación nc=matrix(y4['nc'],(nbr4,1))#nodo común del transformador de tres devanados x31=spmatrix([],[],[],(nbr4,1),tc='d') x32=spmatrix([],[],[],(nbr4,1),tc='d') x33=spmatrix([],[],[],(nbr4,1),tc='d') x12=spmatrix([],[],[],(nbr4,1),tc='d') x13=spmatrix([],[],[],(nbr4,1),tc='d') r31=spmatrix([],[],[],(nbr4,1),tc='d') r32=spmatrix([],[],[],(nbr4,1),tc='d') r33=spmatrix([],[],[],(nbr4,1),tc='d') r12=spmatrix([],[],[],(nbr4,1),tc='d') r13=spmatrix([],[],[],(nbr4,1),tc='d') b31=spmatrix([],[],[],(nbr4,1),tc='d') b32=spmatrix([],[],[],(nbr4,1),tc='d') b33=spmatrix([],[],[],(nbr4,1),tc='d') b12=spmatrix([],[],[],(nbr4,1),tc='d') 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 if nbr2!=0:# si hay líneas en // 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) 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 def ybus():# funcion que genera la matriz ybus global Ypa, Ypm, Y, bc,ds #matrices necesarias para armar la Ybus xc=spmatrix([],[],[],(nbr,1),tc='z') bc=spmatrix([],[],[],(nbr,1),tc='z') x1=spmatrix([],[],[],(nbr,1)) y1=spmatrix([],[],[],(nbr,1)) Y=spmatrix([],[],[],(nnbus,nnbus),tc='z') y=matrix(1,(nbr,1)) Ypr=spmatrix([],[],[],(nnbus,nnbus)) Ypi=spmatrix([],[],[],(nnbus,nnbus)) Ypm=spmatrix([],[],[],(nnbus,nnbus)) Ypa=spmatrix([],[],[],(nnbus,nnbus)) 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 #pasando Ybus de rectangular a polar for n in range(0,nnbus): for k in range(0,nnbus): Ypr[n,k]=Y[n,k].real 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 def cpo():#funcion que genera lamda global lini, angi, Vi, fprlin, fpreaclin, lamdas, cost 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 it=0#variable numero de iteraciones er = 0.00001 #detener el programa si ya se alcanzo la tolerancia dip=5 diq=5 p12=0 p21=0 q12=0 q21=0 gam=0 bet=0 while (dip and diq) > er and it<=100: 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]) def salida():#funcion que genera el reporte global angesgr 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 #generando matrices de datos global nl1,nr1,lam,prgene,prload,nbr1,nlt,nnbus,anges,tbus,V,nombus,pes,qes,R,x,lip,lsp,lipr,lspr B,A,cf,cv,cc #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)) cf=matrix(y['a'],(nnbus,1)) cv=matrix(y['b'],(nnbus,1)) cc=matrix(y['c'],(nnbus,1)) lam=matrix(y['l'],(nnbus,1)) # parametros de las lineas 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 x=matrix(y1['X'],(nbr1,1))#reactancia de linea B=matrix(y1['B'],(nbr1,1))#suceptancia de linea A=matrix(y1['a'],(nbr1,1))#linea o tranformador 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 def cpo():#funcion que genera lamda global lini,ds, cost, lam, fplin 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] #generando la matriz Hessiana MCC=spmatrix([],[],[],(nnbus,nnbus),tc='d') MIMVA=spmatrix([],[],[],(nnbus,nnbus),tc='d') MZERO=spmatrix([],[],[],(nnbus,nnbus),tc='d') MZERO1=spmatrix([],[],[],(nnbus,nnbus-1),tc='d') MZERO2=spmatrix([],[],[],(nnbus-1,nnbus-1),tc='d') MZERO3=spmatrix([],[],[],(nnbus-1,nnbus),tc='d') Y1=spmatrix([],[],[],(nnbus-1,nnbus),tc='d') Y2=spmatrix([],[],[],(nnbus,nnbus-1),tc='d') hes3=spmatrix([],[],[],(3*nnbus-1,bgene)) hes=matrix(0,(dx,dx),tc='d') for i in range(0,nnbus): MCC[i,i]=2*cc[i] MIMVA[i,i]=-1./MVA 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)) it=0#variable numero de iteraciones er = 0.0001 #detener el programa si ya se alcanzo la tolerancia dip=5 diq=5 while (dip and diq) > er and it<=100: c=0 for i in range(0,nnbus): if cv[i]>0: LAM[c]=lam[int(busgene[c])-1] c+=1 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 def salida():#funcion que genera el reporte global angesgr angesgr=spmatrix([],[],[],(nnbus,1)) for i in range(0,nnbus): angesgr[i]=anges[i]*180/pi f = open('reporteOPF'+str(nnbus)+'buses.txt', 'w') format = "%.3f" # imprimiendo voltajes de nodo 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