simulación de transitorios electromagnéticos de sistemas

157
Simulación de transitorios electromagnéticos de sistemas eléctricos de potencia empleando programación de unidades de procesamiento gráfico Juan Gonzalo Cuartas Bouhot Universidad Nacional de Colombia Facultad de Minas Departamento de Energía Eléctrica y Automática Medellín, Colombia 2020

Upload: others

Post on 29-Oct-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Simulación de transitorios electromagnéticos de sistemas

Simulación de transitorios electromagnéticos de sistemas

eléctricos de potencia empleando programación de unidades de

procesamiento gráfico

Juan Gonzalo Cuartas Bouhot

Universidad Nacional de Colombia

Facultad de Minas

Departamento de Energía Eléctrica y Automática

Medellín, Colombia

2020

Page 2: Simulación de transitorios electromagnéticos de sistemas
Page 3: Simulación de transitorios electromagnéticos de sistemas

Simulación de transitorios electromagnéticos de sistemas

eléctricos de potencia empleando programación de unidades de

procesamiento gráfico

Juan Gonzalo Cuartas Bouhot

Tesis o trabajo de investigación presentada(o) como requisito parcial para optar al título

de:

Magíster en Ingeniería – Ingeniería Eléctrica

Director (a):

Ing. Javier Gustavo Herrera Murcia, PhD

Línea de Investigación:

Sistemas Eléctricos de Potencia

Universidad Nacional de Colombia

Facultad de Minas

Departamento de Energía Eléctrica y Automática

Medellín, Colombia

2020

Page 4: Simulación de transitorios electromagnéticos de sistemas
Page 5: Simulación de transitorios electromagnéticos de sistemas

Dedicatoria

Dedico esta tesis a mi familia, a mi amada

novia y a todos aquellos que contribuyeron a

su elaboración.

“¡Actúa en vez de suplicar! ¡Sacrifícate sin

esperanza de gloria ni recompensa! Si quieres

conocer los milagros, hazlos tú antes. Sólo así

podrá cumplirse tu peculiar destino.”

Ludwig van Beethoven

Page 6: Simulación de transitorios electromagnéticos de sistemas
Page 7: Simulación de transitorios electromagnéticos de sistemas

Agradecimientos

Doy un agradecimiento especial a mi tutor de tesis el profesor Javier Herrera Murcia por

su dedicación y su guía, a través de la cual con paciencia y esmero se llegaron a grandes

resultados.

Por otra parte, me permito agradecer a las siguientes instituciones o personas:

A la Facultad de Minas de la Universidad Nacional de Colombia sede Medellín y a

sus profesores quienes contribuyeron a mi formación como magister.

A HMV Ingenieros Ltda. por brindar los espacios de formación que el curso de una

maestría requiere.

A mi familia, amigos y novia por su especial apoyo, impulsándome a continuar hasta

culminar esta investigación.

Page 8: Simulación de transitorios electromagnéticos de sistemas
Page 9: Simulación de transitorios electromagnéticos de sistemas

Resumen y Abstract IX

Resumen

Los sistemas eléctricos de potencia están evolucionando de manera acelerada; nuevos

elementos como las redes inteligentes, las microredes, los compensadores de potencia

reactiva (SVC) y los sistemas de transmisión flexibles (FACTS), obligan a que los sistemas

eléctricos de potencia deban concebirse como sistemas variables de múltiples

dimensiones. En consecuencia, ya no solo es importante satisfacer los requerimientos de

eficiencia, confiabilidad y compatibilidad sino también contar con herramientas capaces de

hacer frente a la complejidad de los sistemas durante las etapas de diseño y operación.

Entre las herramientas utilizadas, se destaca la simulación digital, la cual ha sido

ampliamente usada en el diseño, optimización y predicción del comportamiento de los

sistemas eléctricos de potencia. En esta área, esta tesis propone una metodología para la

simulación de transitorios electromagnéticos en sistemas eléctricos de potencia

monofásicos empleando Unidades de Procesamiento Gráfico (GPU por sus siglas en

inglés). Metodología que se plantea como una alternativa competente en la simulación de

sistemas de gran tamaño, usando herramientas de fácil acceso como las tarjetas gráficas

convencionales o comunes.

La metodología considera un particionamiento de una red monofásica mediante el uso del

Equivalente de Thévenin Multi Área (MATE por sus siglas en inglés), define la utilización

de los modelos a partir de la regla trapezoidal de integración para emular el

comportamiento de los equipos eléctricos en régimen transitorio y plantea la solución de

estos a través de computación paralela con arquitectura de cálculo CUDA.

La metodología es puesta a prueba en sistemas eléctricos de diferentes tamaños y se

obtiene que bajo ciertas condiciones los métodos propuestos representan una mejora en

tiempo respecto a otras metodologías de solución de transitorios en la GPU propuestas en

la literatura.

Palabras clave: Computación paralela, MATE, Dommel, CUDA, Sistemas eléctricos

de potencia, Transitorios electromagnéticos.

Page 10: Simulación de transitorios electromagnéticos de sistemas

X Simulación de transitorios electromagnéticos mediante programación de GPUs

Abstract

Simulation of electromagnetic transients in electric power systems using graphics processing units.

Electrical power systems are evolving in an accelerated way. New technologies as smart

grids, micro grids, Static Var Compensators (SVC) and Flexible AC Transmission Systems

(FACTS) demand to consider electrical power systems as variable and multidimensional

systems. As consequence, it is not only necessary to satisfy efficiency, reliability and

compatibility requirements but also it is required the use of tools and techniques to deal

with the complexity during the design and operation stages of electrical power systems.

Among the tools used, the digital simulation is highlighted because it has been widely used

in the design, optimization and prediction of the behavior of electrical power systems. In

this field, this Thesis proposes a methodology to simulate single-phase electromagnetic

transients using Graphic Processing Units (GPU). Methodology that as seen in the

following. is a proficient alternative in the simulation of high size electrical systems

transients.

The proposed methodology considers a single-phase network partitioning through the use

of Multi Area Thevenin Equivalents (MATE), defines the use of trapezoidal rule based

equivalent models for transients calculation and proposes the solution of the electrical

power systems by techniques of parallel computing with CUDA GPU programming

architecture.

The methodology is tested in electrical power systems of different sizes and it is obtained

that under some given conditions, the proposed techniques represent a calculation time

improvement in comparison with other GPU parallelizing techniques which are normally

proposed in academic literature.

Keywords: Parallel computing, MATE, Dommel, CUDA, Electrical Power Systems,

electromagnetic transients

Page 11: Simulación de transitorios electromagnéticos de sistemas

Tabla de contenido XI

Contenido

Pág.

Resumen ........................................................................................................................ IX

Lista de figuras ............................................................................................................ XIII

Lista de tablas .............................................................................................................. XV

Lista de Símbolos y abreviaturas ............................................................................... XVI

Introducción .................................................................................................................... 1

1. Generalidades de las metodologías de simulación de transitorios electromagnéticos ........................................................................................................... 5

1.1 Simulación tradicional de transitorios electromagnéticos .................................... 7 1.2 Simulación de transitorios electromagnéticos en tiempo real .............................. 8 1.3 Simulación de transitorios electromagnéticos en Unidades de Procesamiento

Gráfico – GPU. ................................................................................................. 10

2. Equivalente de Thévenin Multi Área - MATE ........................................................ 13

3. Regla trapezoidal de integración y Modelos Equivalentes de Dommel .............. 21

4. Implementación de modelos equivalentes de Dommel y particionamiento de red MATE ....................................................................................................................... 31

5. CUDA y programación de unidades de procesamiento gráfico .......................... 41 5.1 Metodología CPU-GPU-1 .................................................................................. 46 5.2 Metodología base con mayor paralelismo CPU-GPU-2 ..................................... 49 5.3 Metodología GPU completa GPU-O .................................................................. 49

6. Simulación a gran escala de transitorios electromagnéticos ............................. 55 6.1 Generación aleatoria de sistemas eléctricos de potencia .................................. 55

6.1.1 Subsistemas empleados ..................................................................... 55 6.1.2 Línea de transmisión empleada .......................................................... 57 6.1.3 Fuente de corriente tipo rampa ........................................................... 57 6.1.4 Conexión de los subsistemas .............................................................. 57

6.2 Comparación en el tiempo de ejecución GPU vs CPU ...................................... 62

7. Conclusiones y trabajos futuros ........................................................................... 69 7.1 Conclusiones .................................................................................................... 69 7.2 Trabajos futuros ................................................................................................ 71

Page 12: Simulación de transitorios electromagnéticos de sistemas

XII Simulación de transitorios electromagnéticos mediante programación de GPUs

A. Anexo 1: Código validación uso modelos equivalentes de Dommel ................. 73

B. Anexo 2: Código implementación MATE + Dommel ............................................ 75

C. Anexo 3: Código computación paralela metodología CPU-GPU-1 ..................... 78

D. Anexo 4: Código computación paralela metodología CPU-GPU 2. .................... 89

E. Anexo 5: Código computación paralela metodología GPU-GPU O .................. 101

F. Anexo 6: Código CUDA para la solución de transitorios de sistema eléctrico aleatorio en la GPU ..................................................................................................... 113

G. Anexo 7: Código en MATLAB para la solución de transitorios de sistema eléctrico aleatorio en la CPU ...................................................................................... 127

H. Anexo 8: Código en MATLAB para la generación de sistemas eléctricos aleatorios ..................................................................................................................... 131

Bibliografía .................................................................................................................. 137

Page 13: Simulación de transitorios electromagnéticos de sistemas

Lista de figuras XIII

Lista de figuras

Figura 1-1. Simulación Hardware In Loop. A partir de [14] ............................................... 6

Figura 1-2. Ejemplo de corriente de cortocircuito, periodos subtransitorio, transitorio y

estable. A partir de [16] .................................................................................................... 7

Figura 1-3. Velocidad de simulación y poder de computación requeridas para algunos

fenómenos y sistemas típicos. A partir de [4] ................................................................... 9

Figura 2-1. Sistema eléctrico de ejemplo empleado para explicar MATE. ...................... 13

Figura 2-2. Proceso de solución metodología MATE ..................................................... 18

Figura 3-1. Diagrama unifilar sistema de estudio. ......................................................... 23

Figura 3-2. Esquema equivalente para el cálculo de transitorios. .................................. 24

Figura 3-3. Diagrama de flujo algoritmo de solución de transitorios con equivalentes de

Dommel. A partir de [21] ................................................................................................. 26

Figura 3-4. Tensión al extremo de la línea – modelos equivalente de Dommel. ............. 28

Figura 3-5. División sistema eléctrico Figura 3-2 ........................................................... 29

Figura 4-1. Topología sistema de estudio, combinación MATE y Dommel ..................... 32

Figura 4-2. Fuente de corriente tipo rampa sistema de estudio. .................................... 32

Figura 4-3. Circuito equivalente a partir de modelos equivalentes de Dommel .............. 33

Figura 4-4. Circuitos equivalentes línea de transmisión del sistema de prueba ............. 34

Figura 4-6. Diagrama de flujo del algoritmo de solución de transitorios con modelos

equivalentes de Dommel y MATE. A partir de [8], [21]. ................................................... 37

Figura 4-7. Voltaje vs tiempo Nodo 3 del sistema A. ...................................................... 39

Figura 4-8. Voltaje vs tiempo nodo 1 del sistema B. ...................................................... 39

Figura 5-1. Jerarquía de hilos CUDA. A partir de [26] .................................................... 42

Figura 5-2. Esquema general de un programa en CUDA. .............................................. 42

Figura 5-3. Código ejemplo con lectura de memoria no consecutiva. A partir de [25]. ... 43

Figura 5-4. Código ejemplo con lectura de memoria consecutiva. A partir de [25] ......... 44

Figura 5-5. Sistema de prueba para programación en CUDA ........................................ 45

Figura 5-6. Algoritmo de solución – Metodología CPU-GPU-1 y metodología CPU-GPU-2

de solución de transitorios en la GPU. Acciones en azul son ejecutadas en la CPU,

acciones en verde en la GPU ......................................................................................... 47

Figura 5-7. Algoritmo de solución – Metodología GPU-O para solución de transitorios en

la GPU. Acciones en azul son ejecutadas en la CPU, acciones en verde en la GPU ..... 50

Figura 5-8. Voltaje vs Tiempo Nodo 2 subsistema A ..................................................... 53

Figura 5-9. Voltaje vs Tiempo Nodo 3 subsistema B ..................................................... 53

Figura 5-10. Voltaje vs Tiempo Nodo 2 subsistema C ................................................... 54

Figura 6-1. Subsistema tipo A ........................................................................................ 56

Figura 6-2. Subsistema tipo B ........................................................................................ 56

Page 14: Simulación de transitorios electromagnéticos de sistemas

XIV Simulación de transitorios electromagnéticos mediante programación de GPUs

Figura 6-3. Algoritmo para definición del subsistema del cual sale cada línea ............... 59

Figura 6-4. Algoritmo para definición del subsistema al cual llega cada línea ................ 61

Figura 6-5. Voltaje vs tiempo extremo inicial de la línea 1 .............................................. 63

Figura 6-6. Voltaje vs tiempo extremo final de la línea 1 ................................................ 63

Figura 6-7. Voltaje vs tiempo extremo inicial de la línea 3 .............................................. 64

Figura 6-8. Voltaje vs tiempo extremo final de la línea 3 ................................................ 64

Figura 6-9. Voltaje vs tiempo extremo inicial de la línea 5 .............................................. 65

Figura 6-10. Comparativo tiempos de ejecución GPU vs CPU ....................................... 66

Figura 6-11. Comparativo tiempo de ejecución por sistema GPU vs CPU. ..................... 67

Page 15: Simulación de transitorios electromagnéticos de sistemas

Lista de tablas XV

Lista de tablas

Pág.

Tabla 1-1: Componentes principales del equipo de cómputo empleado en la

investigación. ................................................................................................................... 4

Tabla 3-1:Circuitos equivalentes de los componentes básicos de una red. A partir de [21]

....................................................................................................................................... 22

Tabla 5-1: Comparación tiempos de ejecución metodologías. ....................................... 52

Page 16: Simulación de transitorios electromagnéticos de sistemas

Lista de símbolos y abreviaturas XVI

Lista de Símbolos y abreviaturas

Símbolos con letras latinas Símbolo Término Unidad SI Definición

A Matriz de admitancias subsistema A S ( 2-1) B Matriz de admitancias subsistema B S ( 2-2)

a Matriz inversa de admitancias subsistema A multiplicada por p

Ω ( 2-10)

b Matriz inversa de admitancias subsistema B multiplicada por q

Ω ( 2-11)

C Capacitancia F Tabla 3-1

𝑒𝐴 Tensiones del subsistema A considerando caso desacoplado

V ( 2-10)

𝑒𝐵 Tensiones del subsistema B considerando caso desacoplado

V ( 2-11)

ℎ𝐴 Corrientes de inyección subsistema A A ( 2-1) ℎ𝐵 Corrientes de inyección subsistema B A ( 2-2)

𝐼𝑘 Término de historia corriente saliendo nodo k modelo de línea ideal

A Tabla 3-1

𝐼𝑘𝑚 Término de historia corriente entre nodos k y m

A Tabla 3-1

𝐼𝑚 Término de historia corriente saliendo nodo m modelo de línea ideal

A Tabla 3-1

𝑖𝑘𝑚 Corriente del nodo k al nodo m A Tabla 3-1

𝐼𝛼 Corrientes de los enlaces entre los subsistemas

A ( 2-6)

L Inductancia H Tabla 3-1

p Matrices de conectividad de los enlaces subsistema A

1 ( 2-6)

q Matrices de conectividad de los enlaces subsistema B

1 ( 2-7)

R Resistencia eléctrica Ω Tabla 3-1 𝑢𝑘 Tensión en nodo k V Tabla 3-1 𝑢𝑘𝑚 Tensión entre los nodos k y m V Tabla 3-1

𝑢𝑚 Tensión en nodo m V Tabla 3-1 𝑉𝐴 Tensiones nodales subsistema A V ( 2-1)

𝑉𝐵 Tensiones nodales subsistema B V ( 2-2)

Z Matriz diagonal con impedancias de cada enlace

Ω ( 2-6)

𝑍𝛼 Vector de impedancias equivalentes vista desde los enlaces

Ω ( 2-19)

Page 17: Simulación de transitorios electromagnéticos de sistemas

Lista de símbolos y abreviaturas XVII

Símbolo Término Unidad SI Definición

𝑍𝑐 Impedancia característica línea de transmisión

Ω Figura 3-1

Símbolos con letras griegas Símbolo Término Unidad SI Definición

α Enlaces entre subsistemas 1 Figura 2-1 ∆t Paso de tiempo s ( 3-2), ( 3-4)

Subíndices Subíndice Término

α Referente a los enlaces entre subsistemas

Abreviaturas Abreviatura Término

CPU Unidad de procesamiento central CHIL Controller Hardware In Loop GPU Unidad de procesamiento gráfico HIL Hardware In Loop MATE Equivalente de Thévenin Multi Área PHIL Power Hardware In Loop

RTS Real Time Simulation (Simulación en tiempo real)

Page 18: Simulación de transitorios electromagnéticos de sistemas
Page 19: Simulación de transitorios electromagnéticos de sistemas

Introducción

Los simuladores de sistemas eléctricos han sido ampliamente usados en su planeación,

diseño y mejora por décadas; a pesar de ello, actualmente y frente a la creciente

complejidad de las redes eléctricas, el enfoque de verificar su comportamiento sin

necesidad de afectar sistemas reales o de construir complejas configuraciones, sigue

estando vigente. Actualmente, para garantizar la seguridad y funcionalidad de los diseños

resulta imprescindible la realización de estudios eléctricos que incluyen simulaciones

computacionales de diversos escenarios y fenómenos en múltiples escalas de tiempo. [1]

Entre el conjunto de simulaciones, es importante destacar la simulación digital de

transitorios electromagnéticos, ya que esta requiere la solución de una gran cantidad de

ecuaciones en el dominio del tiempo implicando recursos computacionales significativos.

Tradicionalmente, para la solución de transitorios electromagnéticos se efectúan tres

pasos: (1) La discretización de las ecuaciones diferenciales asociadas al sistema bajo

estudio, (2) la solución iterativa de ecuaciones algebraicas no lineales y (3) la solución de

ecuaciones algebraicas lineales; pasos que normalmente son desarrollados de manera

secuencial ocasionando que en sistemas de gran tamaño deba aumentarse bien sea el

recurso computacional, o el tiempo de simulación [2].

Con el incremento continuo en el acceso a tecnologías de computación cada vez más

eficientes, nuevas metodologías para la solución de transitorios electromagnéticos han

surgido y nuevos métodos como la computación paralela o en la nube se han destacado

como alternativas para lograr simulaciones cada vez más rápidas y precisas [1], [3]. No

obstante, ante el reto de la eficiencia, las soluciones más comunes se han dado a través

de costosos super computadores y elementos de hardware dedicados, o mediante el uso

de herramientas de software que resultan ser inflexibles o aplican reducciones de los

sistemas eléctricos de potencia sacrificando la precisión de los resultados. [1][4]

Page 20: Simulación de transitorios electromagnéticos de sistemas

2 Simulación de transitorios electromagnéticos mediante programación de GPUs

Lo anterior, ha propiciado un vacío en la exploración de nuevas metodologías de

paralelización combinadas con nuevas herramientas como la programación de Unidades

de Procesamiento Gráfico (GPU por sus siglas en inglés), lo cual se estima facilitaría la

implementación de un simulador eficiente y accesible [4], [5]. En consecuencia, esta tesis

plantea la implementación de una metodología para el cálculo de transitorios

electromagnéticos en sistemas eléctricos de potencia a partir de la implementación de

diferentes estrategias modernas de solución de redes eléctricas y computación paralela en

entornos que involucran el uso de unidades de procesamiento gráfico. Esto con el fin de

lograr principalmente una disminución cuantificable de los tiempos de cálculo invertidos en

este tipo de soluciones, especialmente cuando la escala de los sistemas simulados es

considerable.

En este trabajo se plantearon inicialmente como objetivo general y objetivos específicos

los siguientes:

Objetivo general: implementar una metodología que mejore los tiempos de simulación de

transitorios electromagnéticos de potencia basada en técnicas modernas de solución de

redes eléctricas y de computación paralela.

Objetivos específicos:

Definir el esquema de particionamiento de red que será empleado en la simulación

de transitorios electromagnéticos de sistemas eléctricos de potencia.

Evaluar a partir de técnicas de partición, las condiciones de operación de sistemas

eléctricos de potencia.

Solucionar el sistema eléctrico de potencia a partir de técnicas de computación

paralela

Para el cumplimiento de los anteriores objetivos, esta investigación propuso una

metodología en la cual los sistemas eléctricos de potencia de gran tamaño se dividen en

subsistemas a través del uso de Equivalentes de Thévenin Multi Área – MATE [6]–[8]. A

partir de esto, cada subsistema se soluciona considerando la representación de sus

elementos en modelos equivalentes obtenidos a partir de la regla trapezoidal de integración

o también conocidos como “Equivalentes de Dommel”. La metodología propuesta se aplica

Page 21: Simulación de transitorios electromagnéticos de sistemas

Introducción 3

a redes monofásicas pero su implementación en el caso polifásico sería implementable a

través de los conceptos aquí expuestos.

La implementación conjunta de los equivalentes de Thévenin Multi Área y de los modelos

equivalentes obtenidos a partir de la aplicación de la regla trapezoidal constituye un

significativo aporte de esta investigación. Lo anterior, teniendo en cuenta que en la

literatura revisada relacionada con los equivalentes de Thévenin Multi Área no se utilizan

modelos detallados de la línea de transmisión para el cálculo de transitorios, en su lugar

únicamente se incluye una impedancia de enlace [3], [8]–[10]. El modelo de línea empleado

corresponde al modelo ideal de línea de transmisión, pero la metodología propuesta puede

extenderse a otros modelos más detallados.

Otro aporte relevante de la presente investigación corresponde a la solución de las

ecuaciones asociadas al comportamiento dinámico del sistema eléctrico a partir de

técnicas de computación paralela. Para ello se utiliza la plataforma CUDA en la

implementación de la metodología anteriormente mencionada. Esta plataforma de

computación paralela ha sido desarrollada por la compañía NVIDIA y permite a los

programadores usar una extensión del lenguaje C para codificar algoritmos en unidades

de procesamiento gráfico [11], [12]. Basado en esto, la investigación propone una

ejecución completa de los algoritmos propuestos directamente en la GPU, y un

preprocesamiento llevado a cabo en la CPU. A lo largo del presente documento, se logra

demostrar que al aplicar el enfoque de ejecución propuesto se mejoran los tiempos de

simulación de transitorios electromagnéticos en sistemas eléctricos de gran tamaño en

comparación con el enfoque híbrido CPU – GPU y para grandes escalas, el enfoque

tradicional de ejecución en la CPU.[2], [11], [13].

El documento está organizado de la siguiente manera. En el capítulo 1 de este documento

se presentan algunas metodologías actuales de simulación de transitorios

electromagnéticos. Seguidamente, en el capítulo 2 se explica la utilización de Equivalentes

de Thévenin Multi Área (MATE) como esquema de particionamiento de red. En el capítulo

3, se define el uso de los modelos de Dommel para emular el comportamiento transitorio

de los equipos que constituirán los sistemas eléctricos de potencia de prueba. En el

capítulo 4 se combinan los capítulos 2 y 3, en una implementación de MATE combinada

con los modelos equivalentes de Dommel.

Page 22: Simulación de transitorios electromagnéticos de sistemas

4 Simulación de transitorios electromagnéticos mediante programación de GPUs

Con el entendimiento de las metodologías de paralelización normalmente propuestas en

la literatura y las técnicas de solución de sistemas eléctricos de potencia, explicadas en los

capítulos 2, 3 y 4; el capítulo 5 efectúa una comparación del enfoque “clásico” o

metodología base de paralelización, con un enfoque mixto GPU – CPU y un enfoque de

simulación completamente implementado en la GPU. Como aporte de la investigación se

pone a disposición una metodología que resulta competente en la solución de transitorios

de gran tamaño como se evidencia en el capítulo 6.

Los resultados presentados en esta investigación son consecuencia de la ejecución de los

códigos descritos en los capítulos siguientes y presentados en los anexos. El equipo de

cómputo usado tiene las siguientes especificaciones principales:

Tabla 1-1: Componentes principales del equipo de cómputo empleado en la investigación.

COMPONENTE CARACTERÍSTICAS

Procesador Intel Core I5-8300H 2.30 GHz

Memoria RAM 8 GB DDR4

Unidad de procesamiento

gráfico - GPU

NVIDIA GeForce GTX 1050 con 8036 MB de

memoria total

Page 23: Simulación de transitorios electromagnéticos de sistemas

1. Generalidades de las metodologías de simulación de transitorios electromagnéticos

Una simulación consiste en una representación de la operación o de las características de

un sistema a través del uso de otro [1]. En el contexto de la simulación de sistemas

eléctricos de potencia, según la tecnología empleada, existen diferentes clases de

simulaciones entre las cuales se resaltan las siguientes [14]:

Simulación digital: una simulación de este tipo requiere que todo el sistema,

incluyendo las protecciones, el control y otros accesorios, sean modelados en el

simulador, de manera tal que esta no involucra o requiere de interfaces externas ni

de entradas o salidas análogas y digitales.

Hardware In Loop (HIL por sus siglas en inglés): como se ilustra en la Figura

1-1, en una simulación HIL se emplea un computador como la representación virtual

de un sistema eléctrico el cual intercambia señales con la versión real de un

controlador, protección o equipo bajo prueba. Lo anterior, permite el prototipado,

desarrollo y prueba de sistemas de control y protección reales, sin la necesidad de

que estos sean instalados en sistemas eléctricos de potencia existentes o se

requiera la construcción de una red eléctrica de prueba. Esto reduce

significativamente los costos, el riesgo y permite la detección temprana de errores,

contribuyendo así a reducir fallas en la operación de los sistemas eléctricos.

A su vez, la simulación tipo Hardware In Loop se divide en dos metodologías: Power

Hardware In Loop (PHIL) y Controller Hardware In Loop (CHIL), las cuales son

también mostradas en la Figura 1-1. En la división izquierda de la figura se

presenta la simulación CHIL, la cual comprende un simulador en tiempo real del

que se toman señales que son acondicionadas para ser llevadas a un controlador;

nótese que en este caso no hay amplificación de las señales del simulador en

Page 24: Simulación de transitorios electromagnéticos de sistemas

6 Simulación de transitorios electromagnéticos mediante programación de GPUs

tiempo real para emular la transmisión de potencia eléctrica. En la división derecha

de la figura se tiene también un simulador en tiempo real; Sin embargo, en esta

metodología se utiliza un amplificador con el propósito de generar no solo un

intercambio de señales sino una emulación de transferencia de potencia eléctrica

entre los sistemas conectados.

Figura 1-1. Simulación Hardware In Loop. A partir de [14]

En esta investigación las simulaciones realizadas son completamente digitales; Sin

embargo, la metodología propuesta podría mejorarse hasta aplicarse a simulaciones del

tipo Hardware in Loop con los accesorios pertinentes.

Los sistemas eléctricos de potencia se encuentran sometidos a fenómenos caracterizados

por diferentes formas de onda, frecuencias, magnitudes y orígenes. En consecuencia, las

simulaciones tienen como objetivo llevar a cabo análisis según el fenómeno o perturbación

de interés. Por ejemplo, una simulación de sistemas eléctricos de potencia podrá ser,

según la escala de tiempo, una simulación de régimen transitorio o de régimen

permanente; o según el dominio, una simulación con dominio en frecuencia o dominio en

tiempo.[15]

Como se presenta a continuación, la simulación de transitorios electromagnéticos de

sistemas eléctricos de potencia requiere la solución de un gran conjunto de ecuaciones en

el dominio del tiempo implicando el uso de significativos recursos computacionales.

Mencionada condición, define una necesidad continua de aprovechar adecuadamente los

recursos computacionales disponibles y reducir tiempos de simulación la cual se intensifica

en el caso particular de la simulación en tiempo real.[2]

Page 25: Simulación de transitorios electromagnéticos de sistemas

Generalidades de las metodologías de simulación de transitorios

electromagnéticos

7

1.1 Simulación tradicional de transitorios electromagnéticos

Cuando se presenta una perturbación en un sistema eléctrico de potencia, bien sea por el

impacto de una descarga atmosférica, un cortocircuito o una maniobra, se altera el

equilibrio de energía almacenada en este. Durante esta alteración, intercambios de energía

se llevan a cabo entre los campos eléctricos y magnéticos a las frecuencias naturales del

sistema y a las asociadas a la perturbación; como resultado de ello, las corrientes y voltajes

se desvían de sus formas de onda previas a esta y cuando un nuevo equilibrio es

alcanzado después de un intervalo de tiempo, el sistema retorna a un nuevo estado estable

[15].

Un ejemplo de las alteraciones mencionadas es presentado en la Figura 1-2, la cual

corresponde a la corriente de cortocircuito en una máquina síncrona [16]. En la figura se

identifica que tras la ocurrencia del cortocircuito en el instante t=0s, la corriente presenta

comportamientos variantes en el tiempo distinguiéndose de izquierda a derecha los

periodos subtransitorios, transitorios y de estado estable. Esta investigación se enfocará

en la simulación del comportamiento de las variables eléctricas del circuito en estos

periodos de tiempo.

Figura 1-2. Ejemplo de corriente de cortocircuito, periodos subtransitorio, transitorio y estable. A partir de [16]

Page 26: Simulación de transitorios electromagnéticos de sistemas

8 Simulación de transitorios electromagnéticos mediante programación de GPUs

La teoría del análisis de transitorios electromagnéticos aplicada a sistemas eléctricos de

potencia basada en el análisis nodal y propuesta en el siglo XX [13], es todavía el método

más usado por los programas computacionales de simulación de transitorios

electromagnéticos. Generalmente, este tipo de simulación es aplicada a pequeños

sistemas o a porciones de sistemas de gran envergadura, con el fin de verificar por ejemplo

las sobretensiones a las que teóricamente se verán expuestos algunos equipos, o la

simulación de sistemas de control y protección. Sin embargo, con el desarrollo e

implementación de nuevas tecnologías como las líneas de transmisión en corriente

continua y el crecimiento de la generación a partir de fuentes de energía renovables no

convencionales, se da origen a procesos o perturbaciones transitorias no usuales, lo cual

cambia las características tradicionales de las redes eléctricas y trae nuevos retos a las

simulaciones de sistemas eléctricos de potencia de gran tamaño. En estos ya no solo debe

considerarse la porción de la red o el equipo sino gran parte o todo el sistema en

cuestión.[13]

Es un reto considerable realizar la simulación de transitorios electromagnéticos de un

sistema completo debido a la dificultad de asegurar la precisión y estabilidad de la

simulación a medida que el tamaño del sistema crece [13]. Reto que se intensifica si la

simulación pretende ser de tipo real.

1.2 Simulación de transitorios electromagnéticos en tiempo real

La simulación de transitorios electromagnéticos en tiempo real (RTS por sus siglas en

inglés), es también una simulación de transitorios electromagnéticos, pero se caracteriza

por el hecho de que el modelo debe ser siempre solucionado en pasos de tiempo discretos

y coordinados con el proceso de cálculo o computación.

En la simulación de sistemas eléctricos de potencia se presentan dos tipos de

simulaciones, una simulación del tipo fuera de línea u offline y otra en tiempo real. En las

simulaciones de tipo offline el proceso computacional no tiene que estar sincronizado con

la contraparte real del sistema que se está simulando y puede ser más rápida o lenta que

este. En la simulación en tiempo real, considerando que posiblemente al simulador se

encuentra conectado un controlador o un equipo real, se requiere que el tiempo de

Page 27: Simulación de transitorios electromagnéticos de sistemas

Generalidades de las metodologías de simulación de transitorios

electromagnéticos

9

cómputo inicie y finalice de manera sincronizada con los tiempos reales del sistema y el

fenómeno que se está simulando.[14].

A comparación de la simulación del tipo offline, donde el tiempo para resolver las

ecuaciones puede ser mayor o menor y el momento en el que se presentan los resultados

es irrelevante, en las RTS para cada paso de tiempo el simulador debe leer las entradas,

generar salidas, solucionar las ecuaciones e integrar sus resultados con todos los nodos

de tal manera que estos resultados puedan ser convertidos a señales análogas. En

consecuencia, el paso de tiempo debe ser cuidadosamente seleccionado considerando la

necesidad de reproducir y presentar resultados a la misma velocidad que lo haría la

contraparte real del sistema [1], [14]. En esta investigación la simulación será del tipo

offline; sin embargo, con las herramientas necesarias la metodología propuesta puede ser

optimizada para ser empleada en simulaciones de tiempo real.

En la Figura 1-3, se presentan las características del recurso computacional requerido

como función de las velocidades necesarias de simulación en tiempo real para algunos

sistemas mecánicos y eléctricos. Se observa que las velocidades de simulación son

definidas de acuerdo con el sistema y el fenómeno a analizar y que la velocidad de

simulación seleccionada impone un requisito computacional.

Figura 1-3. Velocidad de simulación y poder de computación requeridas para algunos fenómenos y sistemas típicos. A partir de [4]

Page 28: Simulación de transitorios electromagnéticos de sistemas

10 Simulación de transitorios electromagnéticos mediante programación de GPUs

En respuesta a la exigencia de velocidad en simulaciones eléctricas de sistemas de

potencia de gran tamaño y en particular de las simulaciones en tiempo real, se tienen

diversas alternativas y entre ellas se destaca la simulación de transitorios

electromagnéticos en la GPU como una alternativa accesible y competente. Esta

alternativa es descrita a continuación.

1.3 Simulación de transitorios electromagnéticos en Unidades de Procesamiento Gráfico – GPU.

El cálculo acelerado basado en Unidades de Procesamiento Gráfico - GPU puede ser

definido como el uso de estas en combinación con una unidad central de procesamiento

(CPU) para acelerar aplicaciones de análisis e ingeniería. Esta metodología fue introducida

por la empresa NVIDIA en el año 2007 y se fundamenta en el hecho de que las GPU

poseen miles de núcleos que pueden programarse para procesar las cargas de trabajo de

forma paralela y eficiente. [11], [12]

Con base en lo anterior, el objetivo de una aplicación que use GPUs es el de trasladar las

partes de esta con mayor carga computacional a la GPU y dejar el resto del código

ejecutándose en la CPU, teniendo entonces como resultado que las aplicaciones se

ejecutarán en general más rápido. [2], [11]

Dado lo anterior, se tiene que en la simulación basada en unidades de procesamiento

gráfico (GPU) se parte de un esquema de división del problema principal en problemas

independientes, los cuales pueden ser resueltos paralelamente de manera simultánea. En

el particular de los sistemas eléctricos de potencia, los métodos para realizar la división de

los mismos pueden ser clasificados en las siguientes categorías: geométrico, combinatorio,

matemático, espectral y métodos multinivel [3]. En esta investigación, el sistema eléctrico

de potencia se divide gráficamente, considerando la agrupación de elementos en

subsistemas por su pertenencia a la misma infraestructura o red eléctrica real y la conexión

de estos subsistemas a través de líneas de transmisión. Para la solución paralela y unión

de los múltiples resultados en una única solución, se empleará la metodología llamada

Equivalentes de Thévenin Multi Área (MATE), la cual ha demostrado ser precisa y rápida.

[3], [9]

En la programación de unidades de procesamiento gráfico, se identifican principalmente

dos interfaces de programación: CUDA y OpenCL [17]. OpenCL es un estándar que puede

Page 29: Simulación de transitorios electromagnéticos de sistemas

Generalidades de las metodologías de simulación de transitorios

electromagnéticos

11

ser usado para programar CPUs, GPUs y otros dispositivos de diferentes fabricantes. En

su lugar, CUDA es específico para GPUs fabricadas por NVIDIA. Sin embargo, aunque

OpenCL promete un lenguaje portable para la programación de GPUs, esto involucra

sacrificios en rendimiento en comparación con CUDA [17], [18]. De igual manera, es

posible convertir un código generado en CUDA a uno de OpenCL a través de mínimas

modificaciones. [17]. Como resultado de lo anterior en búsqueda de un mayor rendimiento,

esta investigación utilizará la arquitectura de programación de unidades de procesamiento

gráfico (GPU) CUDA.

En la solución de transitorios de sistemas eléctricos de potencia en las GPU, es común

usar un enfoque híbrido CPU-GPU, donde las partes del problema que no pueden ser

paralelizadas son ejecutadas en la CPU y aquellas que pueden ejecutarse en paralelo se

resuelven en la GPU. Este enfoque involucra un costo computacional asociado a la

transferencia continua de memoria entre la GPU y la CPU. [2], [5],[19]

El desempeño de la programación basada en CUDA depende del nivel de paralelización

del problema que se desee resolver. Para definir un enfoque de solución paralelo de

sistemas eléctricos de potencia de gran tamaño, esta investigación define emplear el

particionamiento y solución de red a partir de equivalentes de Thévenin Multi Área los

cuales son explicados a continuación.

Page 30: Simulación de transitorios electromagnéticos de sistemas
Page 31: Simulación de transitorios electromagnéticos de sistemas

2. Equivalente de Thévenin Multi Área - MATE

El equivalente de Thévenin Multi Área (MATE por sus siglas en inglés) parte del hecho que

una red eléctrica de gran tamaño puede ser dividida en pequeñas partes denominadas

subsistemas. Los subsistemas a su vez estarán unidos por algunas ramas o enlaces que

no harán parte de estos[7], [8]. En el análisis de la interacción de los subsistemas, MATE

hace uso del análisis nodal modificado [20] con el fin de combinar en la misma matriz

ecuaciones nodales y ecuaciones de las ramas que conectan los sistemas, tal como se

explica a continuación.

Para explicar la metodología se tomará como base un ejemplo al igual que el reportado en

[8]. Para este, se propone la siguiente topología de red:

Figura 2-1. Sistema eléctrico de ejemplo empleado para explicar MATE.

Esta red puede ser dividida en dos (2) subsistemas de tamaño aproximadamente igual,

llamados subsistemas A y B, conectados a través de enlaces ∝1 𝑦 ∝2. Si cada subsistema

fuera un sistema totalmente independiente se tendrían las siguientes ecuaciones:

[𝐴][𝑣𝐴] = [ℎ𝐴] ( 2-1)

Page 32: Simulación de transitorios electromagnéticos de sistemas

14 Simulación de transitorios electromagnéticos mediante programación de GPUs

[𝐵][𝑣𝐵] = [ℎ𝐵] ( 2-2)

Para los subsistemas A y B respectivamente. Donde A corresponde a la matriz de

admitancia nodal que involucra a los nodos 1 a 4 y B a la matriz de admitancia nodal que

involucra los nodos 1 a 3, y están dadas por:

𝐴 = [

𝐺𝐴12 + 𝐺𝐴14 −𝐺𝐴12 0 −𝐺𝐴14

−𝐺𝐴12 𝐺𝐴12 + 𝐺𝐴23 −𝐺𝐴23 00 −𝐺𝐴23 𝐺𝐴23 + 𝐺𝐴34 −𝐺𝐴34

−𝐺𝐴14 0 −𝐺𝐴34 𝐺𝐴34 + 𝐺𝐴14

] ( 2-3)

𝐵 = [

𝐺𝐵12 + 𝐺𝐵13 −𝐺𝐵12 −𝐺𝐵13

−𝐺𝐵12 𝐺𝐵12 + 𝐺𝐵23 −𝐺𝐵23

−𝐺𝐵13 −𝐺𝐵23 𝐺𝐵13 + 𝐺𝐵23

] ( 2-4)

Además, con ℎ𝐴 y ℎ𝐵 como las respectivas corrientes de inyección, 𝑣𝐴 y 𝑣𝐵 corresponden

a las tensiones nodales de los nodos de los subsistemas A y B respectivamente.

Las ecuaciones ( 2-1) y ( 2-2) pueden ser combinadas en una única matriz como:

[𝐴 00 𝐵

] [𝑣𝐴

𝑣𝐵] = [

ℎ𝐴

ℎ𝐵] ( 2-5)

Haciendo uso de la técnica de análisis nodal modificado (MNA), en la cual se combinan

ecuaciones nodales con ecuaciones de corriente de ramas, se añaden a la ecuación ( 2-5)

las expresiones asociadas a las corrientes de los enlaces ∝1 𝑦 ∝2, obteniendo:

[

𝐴 0 𝑝0 𝐵 𝑞

𝑝′ 𝑞′ −𝑧] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = [

ℎ𝐴

ℎ𝐵0

] ( 2-6)

Donde 𝐼𝛼 corresponde al vector de corriente de los enlaces 𝛼1 y 𝛼2, 𝐼𝛼 = [𝐼𝛼1, 𝐼𝛼2]′; 𝑝 y 𝑞

corresponden a las matrices de inyección derivadas de los enlaces y asociadas a los

subsistemas A y B respectivamente. Sus elementos tendrán un valor +1 si la corriente sale

del nodo y -1 si entra al mismo. Para la red mostrada en la Figura 2-1, corresponden a las

siguientes matrices:

Page 33: Simulación de transitorios electromagnéticos de sistemas

Equivalentes de Thévenin Multi Área (MATE) 15

𝑝 = [

0 00 0

+1 00 +1

] , 𝑞 = [−1 00 00 −1

] ( 2-7)

𝑝′ y 𝑞′son las matrices transpuestas de las matrices 𝑝 y 𝑞 presentadas anteriormente:

𝑝′ = [0 0 +1 00 0 0 +1

] , 𝑞 = [−1 0 00 0 −1

] ( 2-8)

Nótese que la cantidad de columnas de 𝑝 y 𝑞 corresponde al número de enlaces

involucrados ( 𝛼1 y 𝛼2 en este caso), y la cantidad de filas al número de nodos de los

respectivos subsistemas. Esta es la razón de por qué la matriz 𝑝, asociada al subsistema

A, cuenta con cuatro filas y 𝑞, asociada al subsistema B, con tres filas.

En ( 2-6) 𝑧 corresponde a una matriz diagonal con las impedancias de los enlaces 𝛼1 y 𝛼2:

𝑧 = [𝑧𝛼1

0

0 𝑧𝛼2

]

( 2-9)

En la ecuación ( 2-6) se representa el sistema de forma matricial; Sin embargo, este modelo

implica resolver todos los subsistemas simultáneamente. Con el propósito de encontrar un

conjunto de expresiones que denoten independencia en el proceso de solución, se procede

a operar matemáticamente cada fila de ( 2-6)

En ( 2-6) se multiplica la primera fila por 𝐴−1 y operando:

𝐴−1[𝐴 0 𝑝] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = 𝐴−1[ℎ𝐴]

[𝐴−1𝐴 0 𝐴−1𝑝] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = [𝐴−1ℎ𝐴]

[Ι 0 𝑎] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = [𝑒𝐴] ( 2-10)

De manera análoga, en ( 2-6) se multiplica la fila 2 por 𝐵−1 obteniéndose que:

[0 I 𝑏] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = [𝑒𝐵] ( 2-11)

Page 34: Simulación de transitorios electromagnéticos de sistemas

16 Simulación de transitorios electromagnéticos mediante programación de GPUs

Finalmente, para la última fila de ( 2-6) que representa los enlaces entre subsistemas se

tiene que

[𝑝′ 𝑞′ −𝑧] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = [0] ( 2-12)

De ( 2-10) y ( 2-11) es posible obtener expresiones para 𝑣𝐴 y 𝑣𝐵 en términos de 𝐼𝛼, 𝑒𝐴 y

𝑒𝐵:

𝑣𝐴 = 𝑒𝐴 − 𝑎𝐼𝛼 ( 2-13)

𝑣𝐵 = 𝑒𝐵 − 𝑏𝐼𝛼 ( 2-14)

Al sustituirlas en ( 2-12) se obtiene:

[𝑝′ 𝑞′ −𝑧] [

𝑒𝐴 − 𝑎𝐼𝛼𝑒𝐵 − 𝑏𝐼𝛼

𝐼𝛼

] = [0] ( 2-15)

Expandiendo la ecuación ( 2-15), la expresión resultante es agrupada y escrita en forma

matricial considerando como factor común 𝐼𝛼 :

(𝑝′𝑎 + 𝑞′𝑏 + 𝑧)𝐼𝛼 = 𝑝′𝑒𝐴 + 𝑞′𝑒𝐵

[𝑝′𝑎 + 𝑞′𝑏 + 𝑧] [𝐼𝛼] = [𝑝′𝑒𝐴 + 𝑞′𝑒𝐵] ( 2-16)

El vector de incógnitas de la ecuación ( 2-16) es aumentando con 𝑣𝐴 y 𝑣𝐵 para recuperar

las incógnitas planteadas en la ecuación ( 2-6). En consecuencia, la última fila de la

ecuación ( 2-6) puede ser reemplazada por la siguiente:

[0 0 𝑝′𝑎 + 𝑞′𝑏 + 𝑧] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = [𝑝′𝑒𝐴 + 𝑞′𝑒𝐵] ( 2-17)

Agrupando las ecuaciones ( 2-10), ( 2-11) y ( 2-17) se tiene que:

[1 0 𝑎0 1 𝑏0 0 𝑍𝛼

] [

𝑣𝐴

𝑣𝐵

𝐼𝛼] = [

𝑒𝐴

𝑒𝐵𝑒𝛼

] ( 2-18)

Page 35: Simulación de transitorios electromagnéticos de sistemas

Equivalentes de Thévenin Multi Área (MATE) 17

Con:

𝑎 = 𝐴−1𝑝 𝑒𝐴 = 𝐴−1ℎ𝐴

𝑏 = 𝐵−1𝑞 𝑒𝐵 = 𝐵−1ℎ𝐵

𝑍𝛼 = 𝑝′𝑎 + 𝑞′𝑏 + 𝑧 𝑒𝛼 = 𝑝′𝑒𝐴 + 𝑞′𝑒𝐵

( 2-19)

Nótese que en ( 2-18) en conjunto con las ecuaciones presentadas en ( 2-19), los sistemas

pueden resolverse usando el siguiente proceso de solución[7], [8]:

1. Hallar las tensiones internas de cada subsistema considerando que se encuentran

desacoplados y haciendo uso de las siguientes expresiones, con ℎ𝐴 y ℎ𝐵 siendo las

corrientes de inyección de cada uno de los susbsistemas:

𝑒𝐴 = 𝐴−1ℎ𝐴

𝑒𝐵 = 𝐵−1ℎ𝐵 ( 2-20)

2. Hallar las tensiones vistas desde los enlaces empleando la siguiente expresión:

𝑒𝛼 = 𝑝′𝑒𝐴 + 𝑞′𝑒𝐵 ( 2-21)

3. Hallar las corrientes de los enlaces, usando la inversa de la matriz 𝑍𝛼 definida en

( 2-19):

𝐼𝛼 = 𝑍𝛼−1𝑒𝛼 ( 2-22)

4. Hallar de nuevo los voltajes internos de los subsistemas pero inyectando las

corrientes de enlace calculadas en ( 2-22) y haciendo uso de las siguientes

expresiones, las cuales se derivan de las ecuaciones ( 2-18) y ( 2-19) :

𝑣𝐴 = 𝐴−1(ℎ𝐴 − 𝑝𝐼𝛼)

𝑣𝐵 = 𝐵−1(ℎ𝐵 − 𝑞𝐼𝛼) ( 2-23)

Page 36: Simulación de transitorios electromagnéticos de sistemas

18 Simulación de transitorios electromagnéticos mediante programación de GPUs

En términos generales, la metodología MATE propone el siguiente esquema de solución

Figura 2-2. Proceso de solución metodología MATE

Se ha definido entonces un esquema de particionamiento de red, el cual permite separar

grandes sistemas eléctricos de potencia en subsistemas que pueden ser resueltos de

manera independiente y simultánea.

Para la selección de la estrategia de división de la red en subsistemas se debe tener en

cuenta que un buen esquema de particionamiento debe distribuir a cada unidad de cálculo

o procesador aproximadamente igual número de operaciones y al mismo tiempo debe

minimizar el número de cálculos de enlaces y la comunicación entre unidades de

procesamiento [3].

Teniendo en cuenta que en esta investigación se considera que el sistema eléctrico de

potencia estará conformado por conjuntos o subsistemas que serán de aproximadamente

igual tamaño, se decide realizar la división del sistema eléctrico de potencia a través de un

esquema de particionamiento gráfico, en el cual se establecerán los subsistemas de

acuerdo con la pertenencia de los elementos a la misma infraestructura o red eléctrica real.

De acuerdo con la literatura, los esquemas de particionamiento gráfico pueden ser usados

para relacionar dependencias en la simulación de sistemas de potencia y el

particionamiento a través de los mismos consiste en una buena estrategia para dividir las

operaciones entre las unidades de cálculo o procesadores [3], [8], [9].

De acuerdo con lo anterior, esta investigación propone que los enlaces indicados en la

metodología de los Equivalentes de Thévenin Multi Área correspondan a líneas de

1. Hallar la solución a cada sistema sin

considerar enlaces utilizando (2-20).

2. Con matrices p y q, las tensiones halladas

en 1 y Zα se calculan las corrientes de los

enlaces utilizando (2-21) y (2-22)

3. Con las corrientes de

enlace, se recalculan las

tensiones de los subsistemas y se halla la solución

completa utilizando (2-23)

Page 37: Simulación de transitorios electromagnéticos de sistemas

Equivalentes de Thévenin Multi Área (MATE) 19

transmisión. Enlaces que de acuerdo con la formulación anterior son elementos

concentrados, sin embargo, para solucionar transitorios electromagnéticos de manera

precisa se debe definir el modelo de la línea de transmisión a utilizar, el cual como se indica

en los capítulos siguientes será un modelo de línea con parámetros constantes distribuidos

[21], [22].

Ahora, hemos de preocuparnos por cómo se resolverá cada uno de los subsistemas y

cuáles serán los modelos equivalentes empleados para llegar a una solución rápida y

precisa de los procesos transitorios. Esto es presentado en el capítulo siguiente.

Page 38: Simulación de transitorios electromagnéticos de sistemas
Page 39: Simulación de transitorios electromagnéticos de sistemas

3. Regla trapezoidal de integración y Modelos Equivalentes de Dommel

Las maniobras, fallas, descargas atmosféricas y otras perturbaciones causan sobrevoltajes

o sobrecorrientes temporales en los sistemas eléctricos de potencia. El cálculo riguroso de

estos procesos transitorios resulta ser una tarea difícil debido a la complejidad de los

modelos de los equipos involucrados. Esto ocasiona además, que sea prácticamente

imposible obtener la solución de un proceso transitorio mediante un cálculo manual, incluso

en redes o sistemas bastante simples.[21], [23]

Varias técnicas han sido desarrolladas para simular procesos transitorios mediante

computadora. Estas se pueden dividir en dos categorías principalmente: técnicas en el

dominio de la frecuencia y técnicas en el dominio del tiempo. De los varios métodos

propuestos en el domino del tiempo, el más común es el algoritmo desarrollado por H. W.

Dommel, el cual dio origen al EMTP, la herramienta más empleada en el cálculo de

procesos transitorios.[21]

El método de Dommel permite resolver redes polifásicas con parámetros distribuidos y con

la presencia de elementos lineales y no-lineales. Esta técnica tiene como base la regla

trapezoidal de integración, la cual al ser aplicada a los modelos de los diferentes elementos

permite obtener circuitos equivalentes que facilitan la implementación de una metodología

de cálculo recursiva rápida y precisa.[23]

Con la aplicación de la regla trapezoidal se obtienen los siguientes circuitos equivalentes

de los componentes básicos de una red[21]:

Page 40: Simulación de transitorios electromagnéticos de sistemas

22 Simulación de transitorios electromagnéticos mediante programación de GPUs

Tabla 3-1:Circuitos equivalentes de los componentes básicos de una red. A partir de [21]

Componente Representación

Temporal Circuito equivalente

Resistencia

Inductancia

Capacidad

Línea de

transmisión

ideal

Los anteriores circuitos equivalentes son representados por las siguientes expresiones:

Resistencia:

𝑢𝑘(𝑡) − 𝑢𝑚(𝑡) = 𝑢𝑘𝑚(𝑡) = 𝑅𝑖𝑘𝑚(𝑡) ( 3-1)

Inductancia:

𝑖𝑘𝑚(𝑡) =∆𝑡

2𝐿𝑢𝑘𝑚(𝑡) + 𝐼𝑘𝑚(𝑡)

( 3-2)

𝐼𝑘𝑚(𝑡) = [∆𝑡

2𝐿𝑢𝑘𝑚(𝑡 − ∆𝑡) + 𝑖𝑘𝑚(𝑡 − ∆𝑡)]

( 3-3)

Page 41: Simulación de transitorios electromagnéticos de sistemas

23 Modelos equivalentes de Dommel 23

Capacidad:

𝑖𝑘𝑚(𝑡) =2𝐶

∆𝑡𝑢𝑘𝑚(𝑡) + 𝐼𝑘𝑚(𝑡)

( 3-4)

𝐼𝑘𝑚(𝑡) = − [2𝐶

∆𝑡𝑢𝑘𝑚(𝑡 − ∆𝑡) + 𝑖𝑘𝑚(𝑡 − ∆𝑡)]

( 3-5)

Línea de transmisión ideal:

𝐼𝑘(𝑡) = − [𝑣𝑚(𝑡 − 𝜏)

𝑍𝑐+ 𝑖𝑚𝑘(𝑡 − 𝜏)]

𝐼𝑚(𝑡) = − [𝑣𝑘(𝑡 − 𝜏)

𝑍𝑐+ 𝑖𝑘𝑚(𝑡 − 𝜏)]

( 3-6)

𝑖𝑘𝑚(𝑡) = 𝑢𝑘(𝑡)

𝑍𝑐+ 𝐼𝑘(𝑡)

𝑖𝑚𝑘(𝑡) = 𝑢𝑚(𝑡)

𝑍𝑐+ 𝐼𝑚(𝑡)

( 3-7)

𝜏 =𝑙

𝑣 ( 3-8)

Con:

𝑙:Longitud de la línea de transmisión.

𝑣: velocidad de propagación de ondas, 𝑣 = 300.000 𝑘𝑚/𝑠 .

Para comparar la estrategia de solución tradicional con aquella usando la metodología

MATE y la aplicación de los modelos equivalentes de Dommel, se programa en MATLAB

la solución al siguiente circuito tomado de [21]:

Figura 3-1. Diagrama unifilar sistema de estudio.

Con:

Page 42: Simulación de transitorios electromagnéticos de sistemas

𝑒(𝑡) = 1 𝑉

𝑅0 = 10 Ω

𝑍𝐶 = 350 Ω

𝑣 = 300.000 𝑘𝑚/𝑠

𝐿 = 60 𝑘𝑚

𝐶 = 0.1𝜇𝐹

De acuerdo con los modelos equivalentes presentados en la Tabla 3-1, el circuito anterior

puede ser presentado de la siguiente manera:

Figura 3-2. Esquema equivalente para el cálculo de transitorios.

Aplicando el análisis nodal convencional al circuito de la Figura 3-2 se obtiene el siguiente

sistema de ecuaciones:

[ 1

𝑅0+

1

𝑍𝐶0

01

𝑍𝑐+

2𝐶

Δ𝑡]

[𝑢1(𝑡)

𝑢2(𝑡)] = [

𝑒(𝑡)

𝑅0− 𝐼1(𝑡)

−𝐼2(𝑡) − 𝐼𝐶(𝑡)

] ( 3-9)

De acuerdo con ( 3-6) y ( 3-7) se tiene:

𝐼1(𝑡) = − [𝑢2(𝑡 − 𝜏)

𝑍𝑐+ 𝑖21(𝑡 − 𝜏)] ( 3-10)

𝐼2(𝑡) = − [𝑢1(𝑡 − 𝜏)

𝑍𝑐+ 𝑖12(𝑡 − 𝜏)] ( 3-11)

𝐼𝐶(𝑡) = −[2𝐶

Δ𝑡 𝑢2(𝑡 − Δ𝑡) + 𝑖𝐶(𝑡 − Δ𝑡)] ( 3-12)

A su vez, del sistema original presentado en la Figura 3-1 se obtienen las siguientes

expresiones para las corrientes asociadas a la línea ideal y al capacitor:

𝑖12(𝑡) =1

𝑅0

[𝑒(𝑡) − 𝑢1(𝑡)] ( 3-13)

Page 43: Simulación de transitorios electromagnéticos de sistemas

25 Modelos equivalentes de Dommel 25

𝑖21(𝑡) = −𝑖𝐶(𝑡) ( 3-14)

𝑖𝐶(𝑡) =2𝐶

Δ𝑡𝑢2(𝑡) − [

2𝐶

Δ𝑡𝑢2(𝑡 − Δ𝑡) + 𝑖𝐶(𝑡 − Δ𝑡)] ( 3-15)

Adicional a las ecuaciones anteriores se deben fijar las condiciones iniciales del sistema,

para ello se realizan las siguientes consideraciones:

El sistema de la Figura 3-1 se encuentra inicialmente relajado, por tanto:

𝐼1(0) = 𝐼2(0) = 𝐼𝐶(0) = 0

El interruptor se cierra en 𝑡 = Δ𝑡

Con las ecuaciones y consideraciones anteriores, el algoritmo de la Figura 3-3 es

programado en MATLAB teniendo como resultado el código del anexo 1.

Page 44: Simulación de transitorios electromagnéticos de sistemas

26 Simulación de transitorios electromagnéticos mediante programación de GPUs

Figura 3-3. Diagrama de flujo algoritmo de solución de transitorios con equivalentes de Dommel. A partir de [21]

En resumen, en el código del anexo 1 desarrollado a partir del algoritmo de la Figura 3-3,

se realiza el siguiente procedimiento:

1. Se definen las características de los componentes del sistema: 𝑅0, E, 𝑍𝐶, 𝜏, 𝐶.

2. Se define un paso de tiempo Δ𝑡 = 𝜏/15.

Page 45: Simulación de transitorios electromagnéticos de sistemas

27 Modelos equivalentes de Dommel 27

3. Se definen condiciones iniciales, el sistema se encuentra inicialmente relajado por

tanto todas las corrientes y voltajes en 𝑡 = 0 tienen un valor nulo.

4. Con las variables del paso 1 y de acuerdo con ( 3-9) se construye la siguiente

matriz:

[ 1

𝑅0+

1

𝑍𝐶0

01

𝑍𝑐+

2𝐶

Δ𝑡]

( 3-16)

5. Se invierte la matriz presentada en ( 3-16).

6. Si el paso de tiempo es inferior al paso de tiempo máximo de simulación, se realiza

el siguiente proceso iterativo:

6.1. Con las ecuaciones ( 3-10), ( 3-11) y ( 3-12) se hallan las corrientes 𝐼1, 𝐼2 e 𝐼𝐶.

En el caso de 𝐼1 e 𝐼2 se deben considerar dos escenarios: 𝑡 < 𝜏 y 𝑡 > 𝜏. En el

primer escenario 𝐼1 e 𝐼2 tendrán un valor de 0 A, en el segundo se calculan

con las ecuaciones mencionadas previamente.

6.2. Del paso anterior y con los parámetros del sistema se conoce el vector

presentado en el lado derecho del igual en la ecuación ( 3-9). Se multiplica

entonces la matriz inversa del paso 5 con el vector mencionado anteriormente

y se obtienen las tensiones 𝑢1(𝑡) y 𝑢2(𝑡).

6.3. Con los resultados de los pasos 6.2 y 6.3 se hallan las corrientes 𝑖12, 𝑖21 e 𝑖𝐶

con las ecuaciones ( 3-13), ( 3-14) y ( 3-15).

6.4. Se actualizan el parámetro de tiempo, 𝑡 = 𝑡 + Δ𝑡.

7. Se finaliza la ejecución y se presentan resultados.

Tras la ejecución de este algoritmo con Δ𝑡 = 13,33 𝜇𝑠 y un tiempo máximo de simulación

de 35 𝑚𝑠, se obtiene la forma de onda presentada en la Figura 3-4 en color azul, la cual

corresponde a la tensión al extremo de la línea, es decir medida en el nodo 2 del sistema

de la Figura 3-1. Para validar el procedimiento anterior, el sistema es simulado en ATP

Draw [24] obteniendo el resultado presentado en la Figura 3-4 en color rojo, nótese que

tanto el resultado del procedimiento programado como el de la simulación en ATP Draw

Page 46: Simulación de transitorios electromagnéticos de sistemas

28 Simulación de transitorios electromagnéticos mediante programación de GPUs

tienen la misma forma de onda y presentan una diferencia máxima de 0.59%, lo cual

confirma lo correcto del procedimiento realizado.

Figura 3-4. Tensión al extremo de la línea – modelos equivalentes de Dommel.

De la Tabla 3-1 se tiene que todos los modelos equivalentes de Dommel para el cálculo

de transitorios electromagnéticos emplean elementos resistivos y fuentes de corriente,

elementos que son de fácil cálculo y evitan el uso de números complejos propiciando una

reducción del costo computacional de las operaciones.[3]

Nótese además que, con el uso del modelo equivalente de la línea de transmisión ideal,

se produce un efecto desacoplador ya que la línea es representada por dos circuitos

independientes, los cuales pueden ser asociados a subsistemas o enlaces diferentes. Lo

anterior puede ser aprovechado mediante la metodología MATE descrita en el Capítulo 2.

La combinación de los modelos equivalentes de Dommel y la metodología de

particionamiento de red MATE es presentada en el capítulo siguiente.

El circuito de la Figura 3-2 se podría resolver empleado la metodología de los equivalentes

de Thévenin Multi Área descrita en el capítulo 2 del presente documento. Para ello el

sistema eléctrico de potencia se puede dividir en dos subsistemas considerando a la línea

de transmisión como único enlace como se presenta en la figura Figura 3-5. Tras

realizarse esta división se seguiría el procedimiento de la figura Figura 2-2. Se tiene

Page 47: Simulación de transitorios electromagnéticos de sistemas

29 Modelos equivalentes de Dommel 29

entonces que los modelos equivalentes obtenidos a partir de la aplicación de la regla

trapezoidal y la metodología de los Equivalentes de Thévenin Multi Área pueden

combinarse para calcular los transitorios electromagnéticos de sistemas eléctricos de

potencia. Esta combinación es presentada en el siguiente capítulo.

Figura 3-5. División sistema eléctrico Figura 3-2

Page 48: Simulación de transitorios electromagnéticos de sistemas
Page 49: Simulación de transitorios electromagnéticos de sistemas

4. Implementación de modelos equivalentes de Dommel y particionamiento de red MATE

El objeto de la presente investigación es proponer una metodología para la simulación de

transitorios electromagnéticos en sistemas eléctricos de potencia usando unidades de

procesamiento gráfico (GPUs). La programación en GPUs se fundamenta en la

paralelización del problema, en consecuencia, resulta indispensable la aplicación de un

esquema que permita calcular los transitorios electromagnéticos de un sistema de gran

tamaño dividiendo el mismo en subsistemas, los cuales permitan abordar el problema por

partes para luego consolidar los resultados del sistema completo. Este esquema

corresponde a la combinación de la metodología del equivalente de Thévenin Multi área

descrita en el Capítulo 2, junto con el uso de los modelos equivalentes de Dommel para el

cálculo de transitorios presentados en el capítulo 3. Con el propósito de presentar esta

metodología se parte de un sistema ejemplo.

El sistema objeto de estudio esta dado por dos subsistemas A y B conectados por una

línea de transmisión de longitud conocida y de impedancia característica Zc, tal como se

muestra en la Figura 4-1.

Page 50: Simulación de transitorios electromagnéticos de sistemas

32 Simulación de transitorios electromagnéticos mediante programación de GPUs

Figura 4-1. Topología sistema de estudio, combinación MATE y Dommel

Este sistema cuenta con los siguientes elementos:

𝑰𝑟𝑎𝑚𝑝: fuente de corriente tipo rampa de amplitud máxima 1000 A y tiempo de subida 2 ms,

luego de este tiempo el valor de la fuente será 0 A. La forma de onda de la fuente de

corriente es presentada en la Figura 4-2.

Figura 4-2. Fuente de corriente tipo rampa sistema de estudio.

Además, el resto de los parámetros está dado por:

𝑅𝐴12= 20 Ω

𝑅𝐴23= 10 Ω

𝑅𝐴34= 2,5 Ω

𝑅𝐴14= 5 Ω

Page 51: Simulación de transitorios electromagnéticos de sistemas

Implementación Dommel y MATE 33

𝑅𝐴4= 2 Ω

𝑅𝐵12= 7 Ω

𝑅𝐵23= 5 Ω

𝑅𝐵34= 2 Ω

𝑅𝐵14= 10 Ω

𝑅𝐵4= 8 Ω

𝑍𝑐: 200 Ω , Impedancia característica línea de transmisión de 60 km.

Para definir las condiciones iniciales del sistema, se considera que este se encuentra

desenergizado en t=0 s, es decir todas las corrientes y tensiones tienen un valor nulo.

Es posible observar que el sistema de la Figura 4-1 puede dividirse en dos subsistemas A

y B, unidos por la línea transmisión de impedancia característica Zc. De acuerdo con la

Tabla 3-1 la Figura 4-3 muestra el equivalente del circuito bajo estudio representado en

sus equivalentes circuitales de Dommel.

En la Figura 4-3 se evidencia el efecto desacoplador del modelo equivalente de línea de

transmisión ideal, debido al cual no se tiene un enlace directo de elementos concentrados

entre los sistemas A y B, sino que el modelo de línea permite considerar dos impedancias

y dos corrientes de inyección independientes.

Figura 4-3. Circuito equivalente a partir de modelos equivalentes de Dommel

En primera instancia se hallan las matrices de admitancias de cada uno de los

subsistemas:

Page 52: Simulación de transitorios electromagnéticos de sistemas

34 Simulación de transitorios electromagnéticos mediante programación de GPUs

𝐴 = [

0.25 −0.05 0 −0.20−0.05 0.15 −0.10 0

0 −0.10 0.50 −0.40−0.20 0 −0.40 1.10

] ( 4-1)

𝐵 = [

0.24 −0.14 0 −0.10−0.14 0.34 −0.20 0

0 −0.20 0.70 −0.50−0.10 0 −0.50 0.73

]

( 4-2)

Posterior a ello, se define la matriz de enlace Z:

𝑍 = [𝑍𝛼1 00 𝑍𝛼2

]

( 4-3)

En la Figura 4-3 es posible identificar que, mediante la aplicación de los modelos

equivalentes obtenidos a partir de la aplicación de la regla trapezoidal, la línea de

transmisión es representada como dos circuitos independientes mostrados en la Figura

4-4

Figura 4-4. Circuitos equivalentes línea de transmisión del sistema de prueba

Estos circuitos independientes dan cabida a que en la metodología MATE descrita en el

capítulo 2 una línea de transmisión pueda considerarse como dos enlaces independientes

de impedancias iguales a la impedancia característica de la línea:

𝑍𝛼1 = 𝑍𝛼2 = 𝑍𝑐 ( 4-4)

Page 53: Simulación de transitorios electromagnéticos de sistemas

Implementación Dommel y MATE 35

En consecuencia y como se muestra en las siguientes expresiones, las fuentes de corriente

I1 e I2 de los circuitos equivalentes de la línea de transmisión serán consideradas como

corrientes de inyección de los respectivos subsistemas en los nodos en los cuales se

encuentra conectado cada extremo de la línea.

Por tanto, se definen las siguientes corrientes de inyección para cada subsistema:

𝐼𝐴 = [

𝐼𝑟𝑎𝑚𝑝(𝑡)

0−𝐼1(𝑡)

0

]

( 4-5)

𝐼𝐵 = [

−𝐼2(𝑡)000

]

( 4-6)

A continuación, se determinan las matrices de inyección p y q asociadas a la conexión de

los enlaces, nótese que ambas matrices tienen dos columnas, las cuales corresponden a

cada uno de los enlaces resultantes de la división de la línea de transmisión de acuerdo

con los circuitos equivalentes presentados en la

Figura 4-4. Circuitos equivalentes línea de transmisión del sistema de prueba:

𝑝 = [

0 00 0

+1 00 0

] , 𝑞 = [0 −10 00 0

]

( 4-7)

Se ha de tener en cuenta que 𝐼1(𝑡) e 𝐼2(𝑡) corresponden a las fuentes de corriente del

equivalente de la línea de transmisión mostrado en la Tabla 3-1. Estas corrientes según el

equivalente Dommel, obedecen a las siguientes expresiones:

𝐼1(𝑡) = − [𝑉𝐵1(𝑡 − 𝜏)

𝑍𝑐+ 𝑖1𝐵−3𝐴(𝑡 − 𝜏)]

( 4-8)

𝐼2(𝑡) = − [𝑉𝐴3(𝑡 − 𝜏)

𝑍𝑐+ 𝑖3𝐴−1𝐵(𝑡 − 𝜏)] ( 4-9)

Page 54: Simulación de transitorios electromagnéticos de sistemas

36 Simulación de transitorios electromagnéticos mediante programación de GPUs

Donde:

𝑉𝐵1: Tensión del nodo 1 del sistema B [V].

𝑉𝐴3: Tensión del nodo 3 del sistema A [V].

𝜏: Tiempo de propagación de ondas entre ambos extremos de la línea.

𝜏 =𝑙

𝑣 [𝑠]

( 4-10)

𝑙:longitud de la línea de transmisión, 60 km.

𝑣:velocidad de propagación de la onda, 300.000 km/s. Además,

𝑖12(𝑡) =𝑉𝐴3(𝑡)

𝑍𝑐+ 𝐼1(𝑡)

( 4-11)

𝑖21(𝑡) =𝑉𝐵1(𝑡)

𝑍𝑐+ 𝐼2(𝑡) ( 4-12)

Se destaca que en la solución de la red y considerando el tiempo de propagación de las

ondas en la línea de transmisión, se deben evaluar principalmente dos condiciones: 𝑡 < 𝜏

y 𝑡 ≥ 𝜏.

Con las ecuaciones anteriores, se sigue el proceso de solución de la Figura 4-5 a través

del código generado en MATLAB y presentado en el anexo 2.

Page 55: Simulación de transitorios electromagnéticos de sistemas

Implementación Dommel y MATE 37

Figura 4-5. Diagrama de flujo del algoritmo de solución de transitorios con modelos

equivalentes de Dommel y MATE. A partir de [8], [21].

Page 56: Simulación de transitorios electromagnéticos de sistemas

38 Simulación de transitorios electromagnéticos mediante programación de GPUs

En resumen, este proceso considera las siguientes operaciones:

1. Se definen los parámetros del sistema, las condiciones iniciales, el tiempo máximo

de cálculo y se inicializan los contadores y el parámetro de tiempo.

2. Siempre que el tiempo t sea menor que el tiempo máximo de cálculo se realizan las

siguientes operaciones:

2.1. Se evalúan las corrientes de las líneas de transmisión empleando los

modelos equivalentes obtenidos a partir del uso de la regla trapezoidal, para

ello se consideran dos condiciones:

Si el tiempo t es menor que el tiempo de propagación de las ondas en la

línea de transmisión, las corrientes de la línea 𝐼1(𝑡) e 𝐼2(𝑡) serán 0 A.

Si el tiempo t es mayor o igual que el tiempo de propagación de las ondas

en la línea de transmisión, las corrientes de la línea 𝐼1(𝑡) e 𝐼2(𝑡) deberán

calcularse haciendo uso de las ecuaciones ( 4-8) y ( 4-9).

2.2. Con las corrientes de las líneas calculadas anteriormente se establecen los

vectores de corrientes de inyección de cada subsistema.

2.3. Con las corrientes de inyección y los parámetros de los subsistemas se

sigue la metodología de los equivalentes de Thévenin Multi Área presentada

en el capítulo 2 de la presente investigación para hallar las tensiones y

corrientes de los subsistemas.

2.4. Con las tensiones de los subsistemas se hallan las corrientes 𝑖12(𝑡) e

𝑖21(𝑡) haciendo uso de las ecuaciones ( 4-11) y ( 4-12).

2.5. Se actualiza parámetro de tiempo, 𝑡 = 𝑡 + ∆𝑡.

3. Se repite el proceso del numeral anterior hasta que se alcance el tiempo máximo

de cálculo, cuando esto suceda se detiene el proceso de cálculo y se presentan

resultados.

Tras la ejecución del algoritmo con ∆𝑡 = 20 𝜇𝑠 y un tiempo máximo de simulación de 35 𝑚𝑠,

se obtienen las formas de onda presentadas en la Figura 4-6 en azul y en la Figura 4-7

en azul, las cuales son validadas mediante el uso de ATPDraw obteniendo las curvas

presentadas en rojo en las anteriores figuras.

Page 57: Simulación de transitorios electromagnéticos de sistemas

Implementación Dommel y MATE 39

Figura 4-6. Voltaje vs tiempo Nodo 3 del sistema A.

Figura 4-7. Voltaje vs tiempo nodo 1 del sistema B.

En la Figura 4-6 y en la Figura 4-7 se identifica que tanto la solución programada como la

hallada con ATPDraw siguen la misma forma de onda y son aproximadamente iguales,

adicionalmente se tiene que el porcentaje de error obtenido como una comparación entre

sus valores máximos corresponde al 0.94% y 1.49% respectivamente.

Del ejemplo anterior se destaca que, en el caso de las líneas de transmisión, el valor de la

fuente de corriente asociada al equivalente Dommel de la línea puede ser incluida en la

metodología MATE como una corriente inyectada al subsistema correspondiente. Se

Page 58: Simulación de transitorios electromagnéticos de sistemas

40 Simulación de transitorios electromagnéticos mediante programación de GPUs

resalta además, que con el equivalente de Dommel de la línea de transmisión, esta puede

ser dividida en dos enlaces de igual impedancia característica Zc lo que facilita la aplicación

del equivalente de Thévenin Multi área.

El proceso de solución presentado en la Figura 4-5 puede ser extrapolado a sistemas

eléctricos de potencia de mayor tamaño que el sistema de la Figura 4-1. Para ello bastará

con dividir el sistema eléctrico en subsistemas a través de la definición las líneas de

transmisión como enlaces, estos subsistemas deberán resolverse utilizando los modelos

equivalentes de Dommel y sus expresiones.

En la aplicación de esta metodología a sistemas de gran tamaño se identifica una gran

oportunidad de paralelizar el proceso de solución, paralelización que será lograda a través

del uso de unidades de procesamiento gráfico (GPU) tal como se presenta en los capítulos

5 y 6.

Page 59: Simulación de transitorios electromagnéticos de sistemas

5. CUDA y programación de unidades de procesamiento gráfico

En aplicaciones adecuadas para la paralelización del proceso de solución, las unidades de

procesamiento gráfico (GPU) pueden ofrecer resultados más rápidos en comparación con

las unidades centrales de procesamiento (CPU). Esto es debido principalmente a que las

GPU cuentan con un mayor número de núcleos y su memoria RAM tiene un mayor ancho

de banda que la memoria RAM usada por las CPU. Pese a ello, las GPU no pueden ser

utilizadas por sí solas y requieren que su uso se de en combinación con las CPU, ya que

son estas últimas las encargadas de realizar el preprocesamiento, la gestión de memorias

y de indicar cuando y para que parámetros se deben ejecutar las funciones definidas en la

GPU. [19], [25]

Las funciones que se ejecutan en la GPU se denominan Kernels (“Núcleos” en español).

Estos Kernels se ejecutan de forma paralela dentro de la GPU sobre un conjunto de hilos

llamados threads, los cuales como se muestra en la Figura 5-1 son organizados en una

jerarquía en la que se agrupan en bloques (“blocks”) los que a su vez se pueden distribuir

formando una malla o grid [19], [25].

La cantidad de hilos y los bloques que conforman la malla es especificada por el

programador al invocar un Núcleo. Una vez en la GPU y como se muestra en la Figura

5-1, se asigna a cada hilo y a cada bloque un único número de identificación dentro de la

malla, el cual es usado para indicar a cada hilo cuales son los datos con los que tiene que

trabajar, lo que facilita el direccionamiento de memoria y evita realizar las mismas

operaciones sobre los mismos datos.

Page 60: Simulación de transitorios electromagnéticos de sistemas

42 Simulación de transitorios electromagnéticos mediante programación de GPUs

Figura 5-1. Jerarquía de hilos CUDA. A partir de [26]

En la Figura 5-2 se presenta un esquema general de un programa en la GPU. En este

esquema se destaca que el preprocesamiento que comprende la definición de variables,

la definición de Núcleos y de los parámetros sobre los cuales se ejecutarán los Núcleos,

se ejecutan en la CPU. De igual manera se identifica que debido a que la GPU y la CPU

tienen espacios de memoria diferentes se presentan copias de memoria de la CPU a la

GPU y viceversa.[25]

Figura 5-2. Esquema general de un programa en CUDA.

Page 61: Simulación de transitorios electromagnéticos de sistemas

CUDA y programación de GPUs 43

Para la programación de transitorios en la GPU, esta investigación utiliza el lenguaje

CUDA, el cual corresponde a una extensión de C/C++ para permitir la programación de

tarjetas gráficas fabricadas por NVIDIA [19]. Para la programación se consideran los

siguientes criterios de mejoramiento de la ejecución[25]:

1. Reducir al máximo las operaciones de copia de memoria entre la GPU y la CPU.

2. Considerado que la ejecución de los Núcleos tiene un costo inicial asociado, si la

aplicación no es lo suficientemente grande puede resultar más conveniente

ejecutarla completamente en la CPU. Es decir, la mejora en desempeño de la

programación en la GPU radica en el uso de muchos hilos.

3. Para facilitar los accesos de memoria se recomienda que la cantidad seleccionada

de hilos sea mucho mayor que la cantidad de bloques empleados.

4. Se aprovechará el máximo ancho de banda de la GPU cuando se accede a la

memoria de esta de una manera organizada y secuencial. Esto es llamado “memory

coalescing” y se logra asignando a hilos subsecuentes datos de memoria

subsecuentes [19], [25], [27]. Por ejemplo, considere el siguiente programa:

Figura 5-3. Código ejemplo con lectura de memoria no consecutiva. A partir de [25].

Donde:

blockIdx.x: identificador único de cada bloque de la malla asignada a la

ejecución del Núcleo.

threadIdx.x: identificador único de cada hilo de la malla asignada a la

ejecución del Núcleo.

Output: matriz resultado de la ejecución del programa.

Input: matriz de entrada del programa.

En el código de la Figura 5-3, cuando j=1, el hilo 0 del bloque 0 definirá un valor de

i=0 y en consecuencia, para generar la matriz output deberá consultar el espacio

i = blockIdx.x*blockDim.x + threadIdx.x;

for (j=0; j<N; j++)

output [i] [j] =2 * input [i] [j] ;

Page 62: Simulación de transitorios electromagnéticos de sistemas

44 Simulación de transitorios electromagnéticos mediante programación de GPUs

de memoria correspondiente a input en la posición (0, j=1); el hilo siguiente, es decir

el hilo 1 del bloque 0 definirá un valor de i=1 y consultará el espacio de memoria

correspondiente a input en la posición (1, j=1). Observe entonces que en el código

de la figura Figura 5-3 hilos subsecuentes no consultan espacios de memorias

subsecuentes ya que hay un salto de fila en la matriz input cuando se avanza al

hilo siguiente. Ahora considere el código de la Figura 5-4:

Figura 5-4. Código ejemplo con lectura de memoria consecutiva. A partir de [25]

Observe que cuando i=1, el hilo 0 del bloque 0 definirá un valor de j=0 y leerá el

espacio de memoria correspondiente a input en la posición (i=1, 0); el hilo siguiente,

es decir el hilo 1 del bloque 0 definirá un valor de j=1 y consultará el espacio de

memoria correspondiente a input en la posición (i=1, 1). Nótese que en el código

de la Figura 5-4 hilos subsecuentes sí consultan espacios de memorias

subsecuentes ya que se cambia a la columna siguiente en la matriz input cuando

se avanza al hilo siguiente. Por tanto, se puede afirmar que la lectura de memoria

es secuencial y el resultado práctico se ve reflejado en que se aprovecha a mayor

medida el ancho de banda de la GPU en el código de la Figura 5-4 que en el código

de la Figura 5-3.

En la solución de transitorios de sistemas eléctricos de potencia en las GPU, es común un

enfoque híbrido CPU-GPU, donde las partes del problema que no pueden ser paralelizadas

son ejecutadas en la CPU y aquellas que pueden ejecutarse en paralelo se resuelven en

la GPU asumiendo el costo computacional de la transferencia de memoria entre la GPU y

la CPU [2], [5], [8]. En ese sentido en el proceso de la Figura 4-5, el cálculo de las

corrientes de las líneas es realizado en la CPU, las tensiones de los subsistemas son

halladas con la metodología MATE en la GPU y luego son transferidas a la CPU para ser

utilizadas en el cálculo de los valores históricos de las corrientes de línea de acuerdo con

los modelos equivalentes de Dommel. A este enfoque se le llamará Metodología “CPU-

GPU-1”

j = blockIdx.x*blockDim.x + threadIdx.x;

for (i=0; i<N; i++)

output[i][j] =2*input[i][j];

Page 63: Simulación de transitorios electromagnéticos de sistemas

CUDA y programación de GPUs 45

El enfoque descrito anteriormente se pone a prueba en la solución del sistema de la Figura

5-5 y es comparado con otras dos metodologías: una metodología en la cual se

implementan algunas herramientas de programación con el propósito de incrementar el

nivel de paralelismo del proceso de solución; a este enfoque se le llamará metodología

“CPU-GPU-2” y una metodología GPU completa en la cual todas las operaciones son

realizadas en la GPU a excepción del preprocesamiento y muestra final de resultados; a

esta se le llamará metodología “GPU-O”.

Figura 5-5. Sistema de prueba para programación en CUDA

El Sistema de prueba cuenta con los siguientes elementos:

𝑰𝑟𝑎𝑚𝑝: fuente de corriente tipo rampa de amplitud máxima 1000 A y tiempo de subida

100Δ𝑡, luego de este tiempo el valor de la fuente será 0 A tal como en la Figura 4-2. El

resto de los parámetros están dados por:

Δ𝑡 =1

10∗ (𝜏𝑙í𝑛𝑒𝑎 𝑚á𝑠 𝑐𝑜𝑟𝑡𝑎)

Page 64: Simulación de transitorios electromagnéticos de sistemas

𝑅𝐴12= 20 Ω

𝑅𝐴23= 10 Ω

𝑅𝐴34= 2,5 Ω

𝑅𝐴14= 5 Ω

𝑅𝐴4= 2 Ω

𝑅𝐵12= 7 Ω

𝑅𝐵23= 5 Ω

𝑅𝐵34= 2 Ω

𝑅𝐵14= 10 Ω

𝑅𝐵4= 8 Ω

𝑅𝐶12= 4 Ω

𝑅𝐶23= 8 Ω

𝑅𝐶34= 9 Ω

𝑅𝐶14= 20 Ω

𝑅𝐶4= 5 Ω

Línea 1 de longitud 60 km y 𝑍𝑐𝑙í𝑛𝑒𝑎 1 = 200 Ω

Línea 2 de longitud 40 km y 𝑍𝑐𝑙í𝑛𝑒𝑎 2 = 150 Ω

Línea 3 de longitud 20 km y 𝑍𝑐𝑙í𝑛𝑒𝑎 3 = 180 Ω

5.1 Metodología CPU-GPU-1

En la Figura 5-6 que corresponde al procedimiento de la metodología CPU-GPU-1, se

resaltan en azul los procedimientos llevados a cabo en la CPU y en verde los realizados

en la GPU. Esta metodología es comúnmente usada en la literatura académica; en ella se

implementa la metodología del equivalente de Thévenin Multi Área en la GPU y el resto de

las operaciones son ejecutadas en la CPU. En consecuencia, en cada iteración se presenta

una operación de transferencia de memoria entre la CPU y la GPU y viceversa. El código

en CUDA asociado a la metodología base se presenta en el anexo 3.

Page 65: Simulación de transitorios electromagnéticos de sistemas

CUDA y programación de GPUs 47

Figura 5-6. Algoritmo de solución – Metodología CPU-GPU-1 y metodología CPU-GPU-2 de solución de transitorios en la GPU. Acciones en azul son ejecutadas en la CPU,

acciones en verde en la GPU

Page 66: Simulación de transitorios electromagnéticos de sistemas

48 Simulación de transitorios electromagnéticos mediante programación de GPUs

En resumen, el código presenta la siguiente secuencia de operaciones:

1. Definición de funciones (Núcleos) que se ejecutarán en la GPU.

2. Definición de variables, lectura de matrices inversas y parámetros del sistema. En

este punto se aclara que con el propósito de evitar el cálculo de la inversa dentro

del programa, se decide realizar esta operación previamente en MATLAB como

parte de preprocesamiento y llevarlas a través de un archivo de texto a CUDA.

3. Gestión de memorias. Se asigna espacio en la GPU a las variables que lo requieran

a través de la instrucción CUDA: cudaMalloc.

4. Copia de memoria de la CPU a la GPU de variables que se utilizarán durante la

simulación en la GPU por lo que únicamente se requiere una operación de

transferencia de memoria inicial. Ejemplo: las matrices inversas de los sistemas y

la matriz inversa 𝑍𝛼.

5. Inicio ciclo iterativo hasta cumplirse el tiempo máximo de simulación.

5.1 Cálculo en la CPU de las corrientes de las líneas de acuerdo con el modelo

equivalente de Dommel descrito en el capítulo 3.

5.2 Asignación de las corrientes de inyección de cada subsistema.

5.3 Copia de las corrientes de inyección de cada subsistema de la CPU a la GPU.

5.4 Ejecución en la GPU de la Metodología MATE descrita en el capítulo 2.

5.5 Copia de las tensiones nodales de la GPU a la CPU.

5.6 Actualización en la CPU de las corrientes históricas asociadas al modelo de

la línea.

5.7 Actualización de tiempo t, 𝑡 = 𝑡 + Δ𝑡.

6. Terminar ejecución y presentar resultados.

Al ejecutar el algoritmo de solución de transitorios electromagnéticos para el sistema de la

figura Figura 5-5 siguiendo la metodología CPU-GPU-1 descrita en esta sección con

Δ𝑡 = 6,66 𝜇𝑠 y un tiempo máximo de simulación de 35 𝑚𝑠, se obtiene un tiempo de cálculo

promedio en 10 ejecuciones de 2,51 segundos. El algoritmo de solución es presentado en

el anexo 3.

Page 67: Simulación de transitorios electromagnéticos de sistemas

CUDA y programación de GPUs 49

5.2 Metodología base con mayor paralelismo CPU-GPU-2

El procedimiento de la metodología base con mayor paralelismo CPU-GPU-2 es el mismo

de la metodología CPU-GPU-1 presentada en la Figura 5-6. A diferencia de la metodología

CPU-GPU-1, en esta metodología se implementan las siguientes herramientas que brinda

CUDA para incrementar el paralelismo de la aplicación:

Streams: un stream corresponde a una organización de los hilos en un mismo flujo

o conjunto para permitir concurrencia entre los núcleos. En las operaciones en el

mismo stream se establece el esquema “primeras en entrar primeras en salir” y no

pueden ocurrir simultáneamente; operaciones con streams diferentes asignados no

tienen un orden definido y pueden ocurrir simultáneamente [28]. En el caso del

sistema de la Figura 5-5 se asigna un stream por cada subsistema.

Copia de memoria asíncrona: la instrucción cudamemcpyAsync permite la

transferencia de memoria entre la CPU y la GPU y viceversa de manera asíncrona

según el stream asignado a la operación de copia de memoria. En ese sentido, si

varias operaciones de transferencia de memoria son asignadas al mismo stream

estas serán ejecutadas en el orden del código y no podrá existir concurrencia en

las mismas; en caso contrario, si operaciones de transferencia de memoria se

asignan a diferentes streams, estas operaciones no tendrán un orden y podrán

ejecutarse simultáneamente. Con esta instrucción la copia de memoria se realiza

de manera independiente para cada uno de los subsistemas.

La aplicación de las anteriores herramientas es presentada en el anexo 4. Con la aplicación

de estas con Δ𝑡 = 6,66 𝜇𝑠 y un tiempo máximo de simulación de 35 𝑚𝑠, se obtiene un

tiempo de cálculo promedio en 10 ejecuciones de 1,67 segundos.

5.3 Metodología GPU completa GPU-O

En las metodologías anteriores CPU-GPU-1 y 2 se tiene un alto costo computacional de la

transferencia de memoria entre la CPU y la GPU presentada en cada iteración del proceso

de solución. Como consecuencia de lo anterior se propone el esquema de solución

presentado en la Figura 5-7, en el cual se resaltan en azul las operaciones realizadas en

la CPU y en verde las llevadas a cabo por la GPU. En la metodología GPU-O se utilizan

Page 68: Simulación de transitorios electromagnéticos de sistemas

50 Simulación de transitorios electromagnéticos mediante programación de GPUs

también las herramientas de paralelización presentadas en el numeral 5.2. El código en

CUDA asociado a la metodología GPU-O se presenta en el anexo 5

Figura 5-7. Algoritmo de solución – Metodología GPU-O para solución de transitorios en la GPU. Acciones en azul son ejecutadas en la CPU, acciones en verde en la GPU

En resumen, el código propuesto presenta la siguiente secuencia de operaciones:

1. Definición de funciones (Núcleos) que se ejecutaran en la GPU. Considerando que

en esta metodología todo el proceso de solución será ejecutado en la GPU, se

Page 69: Simulación de transitorios electromagnéticos de sistemas

CUDA y programación de GPUs 51

definen muchos más Núcleos que los empleados en la metodología de la

sección 5.1

2. Definición de variables, lectura de matrices inversas y parámetros del sistema.

3. Gestión de memorias. Se asigna espacio en la GPU a las variables que lo requieran

a través de la instrucción cudaMalloc.

4. Copia de memoria de la CPU a la GPU, se copian a la GPU todas las variables que

se utilizarán en el cálculo

5. Inicio ciclo iterativo hasta cumplirse el tiempo máximo de simulación.

5.1 Cálculo en la GPU de las corrientes de las líneas de acuerdo con el modelo

equivalente de Dommel descrito en el capítulo 3.

5.2 Asignación en la GPU de las corrientes de inyección de cada subsistema.

5.3 Ejecución en la GPU de la Metodología MATE descrita en el capítulo 2.

5.4 Actualización en la GPU de las corrientes históricas asociadas al modelo de

la línea.

5.5 Actualización de tiempo t, 𝑡 = 𝑡 + Δ𝑡.

6. Terminar ejecución, copiar resultados a la CPU y presentarlos

La principal diferencia entre esta metodología y las anteriores CPU-GPU-1 y 2, es que esta

ejecuta muchas más funciones en la GPU sin importar que se trate de funciones serie o

no paralelas. Lo anterior con el propósito de evitar operaciones de transferencia de

memoria en el ciclo iterativo y el alto costo que esto representa.

Al ejecutar el anterior algoritmo de solución de transitorios electromagnéticos para el

sistema de la figura Figura 5-5 con Δ𝑡 = 6,66 𝜇𝑠 y un tiempo máximo de simulación de

35 𝑚𝑠, se obtiene un tiempo de cálculo promedio en 10 ejecuciones de 1,37 segundos.

En resumen, al comparar las metodologías CPU-GPU-1, CPU-GPU-2 y GPU-O, se obtienen

los siguientes tiempos:

Page 70: Simulación de transitorios electromagnéticos de sistemas

52 Simulación de transitorios electromagnéticos mediante programación de GPUs

Tabla 5-1: Comparación tiempos de ejecución metodologías.

Metodología

Metodología CPU-GPU-1

Metodología CPU-GPU-2

Metodología GPU-O

Tiempo de cálculo (s) 2.51 1.67 1.37

Porcentaje de reducción (%)1 0% 34% 45%

Los tiempos reportados en la Tabla 5-1 consideran únicamente el tiempo de cálculo y no

tienen en cuenta el tiempo de preprocesamiento. Los valores presentados corresponden

al tiempo de cálculo promedio de 10 ejecuciones.

Con la aplicación de las tres metodologías descritas en el presente capítulo sobre el

sistema de la Figura 5-5 se obtienen las mismas formas de onda, las cuales como se

muestra en la Figura 5-8, Figura 5-9 y Figura 5-10 son validadas mediante el uso de

ATP/EMTP. En la Figura 5-10 se presentan unas pequeñas diferencias entre la forma de

onda de las metodologías calculadas en CUDA y la simulada en ATP/EMTP. Esta

diferencia se debe a la transferencia de matrices entre MATLAB y CUDA, en la cual se

pierden algunas cifras significativas. Si se incrementan las cifras significativas de los

componentes de las matrices que son transferidos de MATLAB a CUDA y viceversa, los

resultados de los cálculos transitorios y de la simulación en ATP serán aproximadamente

iguales.

1 Los porcentajes de reducción presentados son calculados tomando como base el tiempo de

ejecución de la metodología base señalada en el numeral 5.1.

Page 71: Simulación de transitorios electromagnéticos de sistemas

CUDA y programación de GPUs 53

Figura 5-8. Voltaje vs Tiempo Nodo 2 subsistema A

Figura 5-9. Voltaje vs Tiempo Nodo 3 subsistema B

Page 72: Simulación de transitorios electromagnéticos de sistemas

54 Simulación de transitorios electromagnéticos mediante programación de GPUs

Figura 5-10. Voltaje vs Tiempo Nodo 2 subsistema C

Se obtiene entonces como resultado de la presente investigación, que la metodología

propuesta GPU-O la cual es indicada en la Figura 5-7, representa una significativa

reducción del 45% en el tiempo de ejecución en comparación con la metodología

comúnmente propuesta por la literatura académica.

De acuerdo con lo descrito en el presente capítulo, hasta ahora los sistemas objeto de

estudio han contado con un máximo de tres subsistemas, es por ello que en el próximo

capítulo se define un algoritmo para la creación aleatoria de múltiples sistemas y se efectúa

una comparación del desempeño GPU vs CPU en la solución de transitorios

electromagnéticos de sistemas eléctricos de potencia de gran tamaño.

Page 73: Simulación de transitorios electromagnéticos de sistemas

6. Simulación a gran escala de transitorios electromagnéticos

En este capítulo se realiza una comparación del desempeño en la solución de transitorios

electromagnéticos del uso de unidades de procesamiento gráfico (GPU) versus el uso de

unidades de procesamiento central (CPU). En ambos escenarios se realiza un

particionamiento de la red a través de los equivalentes de Thévenin Multi Área y se

solucionan los transitorios electromagnéticos empleando los modelos equivalentes de

Dommel. En el caso de la solución en la CPU se emplea un programa generado en

MATLAB descrito en el anexo 6 y para la solución en la GPU se utiliza la metodología

“GPU-O” descrita en el capítulo anterior, para ello se desarrolla en CUDA el código

presentado en el anexo 7. Estos programas son utilizados en sistemas de tamaño y

topología variable los cuales son creados aleatoriamente como se describe a continuación.

6.1 Generación aleatoria de sistemas eléctricos de potencia

Para la creación aleatoria de sistemas eléctricos de potencia de prueba con topologías y

tamaños variables se definen las siguientes consideraciones:

6.1.1 Subsistemas empleados

Se utilizarán dos tipos de subsistemas, el subsistema tipo A para el primer subsistema y

subsistema tipo B para el resto de los subsistemas. Estos tendrán las siguientes

características:

Subsistema tipo A: mostrado en la Figura 6-1 es un sistema de cuatro nodos

conformado por elementos resistivos de las siguientes características:

𝑅𝐴12= 20 Ω 𝑅𝐴23

= 10 Ω

Page 74: Simulación de transitorios electromagnéticos de sistemas

56 Simulación de transitorios electromagnéticos mediante programación de GPUs

𝑅𝐴34= 2,5 Ω

𝑅𝐴14= 5 Ω

𝑅𝐴4= 2 Ω

Figura 6-1. Subsistema tipo A

Subsistema tipo B: mostrado en la Figura 6-2 es un sistema de cuatro nodos

conformado por elementos resistivos de las siguientes características:

𝑅𝐵12= 7 Ω

𝑅𝐵23= 5 Ω

𝑅𝐵34= 2 Ω

𝑅𝐵14= 10 Ω

𝑅𝐵4= 8 Ω

Figura 6-2. Subsistema tipo B

Page 75: Simulación de transitorios electromagnéticos de sistemas

Simulación a gran escala de transitorios electromagnéticos 57

6.1.2 Línea de transmisión empleada

Para facilitar la creación de sistemas aleatorios de topologías y tamaños variados, se

empleará únicamente un tipo de línea, la cual tendrá una longitud de 60 km y una

impedancia característica Zc de 200 Ω. Se utilizará igual cantidad de líneas y de

subsistemas.

6.1.3 Fuente de corriente tipo rampa

Para excitar el sistema creado aleatoriamente se define la utilización de una fuente tipo

rampa de amplitud máxima 10.000 A y tiempo de subida 100Δ𝑡, luego de este tiempo el

valor de la fuente será 0 A. Esta fuente se conectará al primer nodo del primer subsistema

que se encuentre disponible luego de asignadas las conexiones de las líneas con la

metodología presentada a continuación.

6.1.4 Conexión de los subsistemas

De acuerdo con la metodología MATE descrita en el capítulo 2, la forma en que los

subsistemas están interconectados se encuentra descrita por las matrices de conectividad

p asociadas a cada subsistema. Considerando el efecto desacoplador del modelo

equivalente de Dommel para las líneas de transmisión, se tiene que cada línea es dividida

en dos enlaces y en consecuencia para cada subsistema la matriz de conectividad p será

una matriz de orden 𝑁 × (𝐿 × 2), siendo N el número de nodos de cada subsistema y L el

número total de líneas del sistema eléctrico de potencia.

En esta matriz p las columnas impares se refieren a la salida de la línea y las columnas

impares a la llegada; cuando la línea sale se asigna un +1 en el nodo correspondiente y

cuando la línea llega se asigna un -1 en el nodo de llegada. Se definen entonces los

siguientes algoritmos para establecer conexión entre los subsistemas.

Algoritmo de definición subsistema de salida de la línea: el algoritmo

presentado en la Figura 6-3 establece como condición que cada subsistema

sea como mínimo el punto de salida de una línea. En ese sentido recorre

secuencialmente los subsistemas seleccionando aleatoriamente el nodo de

Page 76: Simulación de transitorios electromagnéticos de sistemas

58 Simulación de transitorios electromagnéticos mediante programación de GPUs

partida con la restricción de que a un mismo nodo no puede salir o llegar más

de una línea.

En este algoritmo se realiza el siguiente procedimiento:

1. Se asigna un contador i para recorrer todas las líneas. Debido a la

condición de que cada subsistema sea como mínimo el punto de salida

de una línea de transmisión, se define el contador c que servirá para

recorrer todos los subsistemas y como cada línea representa una

columna de las matrices de conectividad p, se define contador h para

recorrer las columnas de p.

2. Se genera aleatoriamente un nodo de conexión; si este nodo se

encuentra disponible se asigna un +1, lo cual indica que en el nodo k

del subsistema c sale la línea i. En caso tal que el primer nodo generado

aleatoriamente no se encuentre disponible, es decir ya tenga una

conexión, se generará aleatoriamente otro nuevo hasta encontrar uno

disponible.

3. Se actualizan contadores i, c y h. Para c se tiene en cuenta que este

recorre M subsistemas. En caso de que sean más enlaces que

subsistemas, se recorrerán los subsistemas de manera cíclica

asignando salidas de línea en los nodos disponibles. El contador h crece

de dos en dos ya que las columnas impares de la matriz de conectividad

p son las que hacen alusión a los nodos de partida de las líneas de

transmisión.

4. Una vez se hayan asignado los nodos y subsistemas de todas las líneas

de transmisión se finaliza la ejecución.

Page 77: Simulación de transitorios electromagnéticos de sistemas

Simulación a gran escala de transitorios electromagnéticos 59

Figura 6-3. Algoritmo para definición del subsistema del cual sale cada línea

Page 78: Simulación de transitorios electromagnéticos de sistemas

60 Simulación de transitorios electromagnéticos mediante programación de GPUs

Algoritmo de definición subsistema de llegada de la línea: el algoritmo

presentado en la Figura 6-4 establece como restricciones que ninguna línea

podrá salir y llegar al mismo sistema, y que de un mismo nodo no puede salir o

llegar más de una línea.

En este algoritmo se realiza el siguiente procedimiento:

1. Se asigna un contador i para recorrer todas las líneas. Aleatoriamente

se preselecciona un subsistema c y como cada línea representa una

columna de las matrices de conectividad p, se define contador h para

recorrer las columnas de p.

2. Se genera aleatoriamente un nodo de conexión y se verifica que el

subsistema de llegada de la línea de transmisión no sea el mismo de

salida, de igual manera se verifica que el nodo seleccionado se

encuentre disponible. En caso de que alguna de las dos condiciones

anteriores no se cumpla, se generará aleatoriamente un nodo y

subsistema de conexión hasta que se satisfagan las restricciones.

3. Una vez se ha encontrado un subsistema y un nodo disponible, se

asigna un -1 en la respectiva posición de la matriz de conectividad. Este

-1 indica que en al nodo k del subsistema c sale la línea i.

4. Se actualizan contadores i y h y se preselecciona aleatoriamente el

sistema c de conexión. El contador h crece de dos en dos ya que las

columnas pares de la matriz de conectividad p son las que hacen alusión

a los nodos de llegada de las líneas de transmisión.

5. Una vez se hayan asignado los nodos y subsistemas de todas las líneas

de transmisión se finaliza la ejecución.

Page 79: Simulación de transitorios electromagnéticos de sistemas

Simulación a gran escala de transitorios electromagnéticos 61

Figura 6-4. Algoritmo para definición del subsistema al cual llega cada línea

Page 80: Simulación de transitorios electromagnéticos de sistemas

62 Simulación de transitorios electromagnéticos mediante programación de GPUs

Con las matrices de conectividad p y los parámetros de los subsistemas y de la línea

descritos anteriormente, se definen las matrices y vectores requeridos para la solución de

los transitorios electromagnéticos del sistema generado aleatoriamente de acuerdo con lo

presentado en la sección 5.3 del presente documento de acuerdo con el procedimiento de

la Figura 5-7. El código de solución desarrollado en lenguaje CUDA es presentado en al

anexo 6.

El proceso de cálculo de transitorios electromagnéticos en la GPU es comparado en

desempeño y precisión con la solución transitoria en la CPU, para ello se sigue la

metodología presentada en el capítulo 4 de la presente investigación de acuerdo con el

procedimiento de la Figura 4-5. El código de solución de transitorios en la CPU es

presentado en el anexo 7.

6.2 Comparación en el tiempo de ejecución GPU vs CPU

Para realizar una comparación del desempeño de la solución de transitorios

electromagnéticos mediante el uso de GPU versus el uso de CPU, se ejecutan los códigos

de los anexos 6 y 7, los cuales corresponden a la solución de transitorios en la CPU y en

la GPU respectivamente. Estos códigos son empleados sobre los sistemas eléctricos de

potencia generados aleatoriamente a partir de las definiciones de la sección 6.1 de este

documento. El código de generación de sistemas aleatorios de potencia es presentado en

el anexo 8.

La solución transitoria del sistema generado aleatoriamente conteniendo hasta 2000

subsistemas es hallada en un equipo que de acuerdo con la Tabla 1-1 posee una unidad

de procesamiento gráfico NVIDIA GeForce GTX 1050 y un procesador Intel Core I5 8500H.

Tras la ejecución en la GPU y en la CPU de los códigos de solución de transitorios

electromagnéticos, anexos 6 y 7 respectivamente, con Δ𝑡 = 20 𝜇𝑠 y con un tiempo máximo

de simulación de 35 𝑚𝑠, se obtienen para un sistema de 5 subsistemas las siguientes

formas de onda:

Page 81: Simulación de transitorios electromagnéticos de sistemas

Simulación a gran escala de transitorios electromagnéticos 63

Figura 6-5. Voltaje vs tiempo extremo inicial de la línea 1

Figura 6-6. Voltaje vs tiempo extremo final de la línea 1

Page 82: Simulación de transitorios electromagnéticos de sistemas

64 Simulación de transitorios electromagnéticos mediante programación de GPUs

Figura 6-7. Voltaje vs tiempo extremo inicial de la línea 3

Figura 6-8. Voltaje vs tiempo extremo final de la línea 3

Page 83: Simulación de transitorios electromagnéticos de sistemas

Simulación a gran escala de transitorios electromagnéticos 65

Figura 6-9. Voltaje vs tiempo extremo inicial de la línea 5

En las formas de onda anteriores se evidencia que se obtienen aproximadamente la misma

solución transitoria del sistema aleatoriamente generado tanto mediante el uso de la GPU

como de la CPU. La diferencia presentada entre las formas de onda es atribuible al

redondeo llevado a cabo cuando se exportan desde MATLAB las matrices a CUDA

mediante ficheros de texto.

Adicionalmente, en la Figura 6-10 se presenta un comparativo en los tiempos de ejecución

de los programas de solución de transitorios electromagnéticos. En esta se evidencia que

cuando el sistema eléctrico de potencia tiene pocos subsistemas resulta más competente

la solución de estos mediante el uso de CPUs. Sin embargo, a medida que el sistema crece

en tamaño y complejidad, la brecha en tiempo de ejecución entre la GPU y la CPU se

reduce progresivamente, alcanzando un punto a partir del cual resulta más competente

implementar estrategias basadas en la programación de unidades de procesamiento

gráfico. A simple vista puede parecer que la diferencia entre los tiempos de ejecución en

la GPU y la CPU no es mucha, sin embargo, los 25 segundos de diferencia presentados

entre el tiempo de simulación en la GPU y la CPU cuando el tamaño del sistema eléctrico

de potencia es de 2000 subsistemas, es una diferencia que puede ser ventajosa cuando

por ejemplo se ejecutan análisis que involucran miles de ejecuciones como los análisis de

confiabilidad o análisis de Montecarlo.

Page 84: Simulación de transitorios electromagnéticos de sistemas

66 Simulación de transitorios electromagnéticos mediante programación de GPUs

Figura 6-10. Comparativo tiempos de ejecución GPU vs CPU

En la Figura 6-11 se presenta la razón de incremento en el tiempo de ejecución al crecer

el número de subsistemas de los sistemas eléctricos de potencia de prueba. La razón de

incremento en tiempo de ejecución es hallada como el cociente entre el tiempo de

ejecución con 𝑀 subsistemas y un tiempo base, el cual corresponde al tiempo de ejecución

para un sistema compuesto por dos subsistemas y dos líneas. En la Figura 6-11 resulta

evidente la paralelización del proceso de solución obtenida en el uso de unidades de

procesamiento gráfico, ya que por ejemplo cuando el tamaño del sistema es de 500

subsistemas, es decir el tamaño se ha multiplicado 250 veces respecto al sistema base,

en la CPU el tiempo de ejecución se ha multiplicado aproximadamente 600 veces y en su

lugar el tiempo de ejecución en la GPU se ha multiplicado únicamente 54 veces.

Se destaca que el tiempo base utilizado para el cálculo de la razón de incremento es

diferente en el caso de la simulación en la CPU y en la GPU, siendo 39635 𝜇𝑠 para la CPU

y 795769 𝜇𝑠 para la GPU. La alta diferencia en los tiempos base de cálculo justifica el

hecho de que aunque en la Figura 6-11 la diferencia entre la GPU y la CPU es considerable

en la Figura 6-10 no sea tan notoria.

0

50

100

150

200

250

300

350

0 500 1000 1500 2000

Tie

mp

o d

e e

jecució

n (

s)

Cantidad de subsistemas

Comparativo tiempos de ejecución

GPU

CPU

Page 85: Simulación de transitorios electromagnéticos de sistemas

Simulación a gran escala de transitorios electromagnéticos 67

Figura 6-11. Comparativo tiempo de ejecución por sistema GPU vs CPU.

Resulta importante identificar que en esta comparación la unidad de procesamiento gráfico

GPU disponible, la cual corresponde a la NVIDIA GeForce GTX 1050, tiene un poder de

cálculo bastante inferior al procesador Intel Core I5 8300H por lo que el tamaño del sistema

en el cual resulta más competente emplear unidades de procesamiento gráfico

corresponde a una cantidad de subsistemas considerable. Esta cantidad de subsistemas

es plausible si se considera la complejidad de los subsistemas empleados, ya que en la

realidad se pueden encontrar sistemas con múltiples elementos y diferentes niveles de

tensión que resultan mucho más complejos que el sistema eléctrico de prueba empleado.

La cantidad de subsistemas a partir de la cual resulta más competente el uso de unidades

de procesamiento gráfico en lugar de CPUs se puede reducir empleando GPUs

especializadas con un mayor desempeño en el cálculo paralelo como la Tesla V100-SXM2.

[29]

0

1,000

2,000

3,000

4,000

5,000

6,000

7,000

8,000

9,000

0 500 1000 1500 2000

Tie

mpo d

e e

jecució

n/ tiem

po d

e e

jecució

n b

ase

Cantidad de subsistemas

Crecimiento en el tiempo de ejecución

GPU

CPU

Page 86: Simulación de transitorios electromagnéticos de sistemas
Page 87: Simulación de transitorios electromagnéticos de sistemas

7. Conclusiones y trabajos futuros

7.1 Conclusiones

De acuerdo con los resultados de los capítulos 5 y 6 del presente documento se puede

afirmar que se ha cumplido el objetivo general de esta investigación, el cual corresponde

a “implementar una metodología que mejore los tiempos de simulación de transitorios

electromagnéticos de potencia basada en técnicas modernas de solución de redes

eléctricas y de computación paralela”. Lo anterior debido a que se ha propuesto una

metodología de solución de transitorios mediante el uso de unidades de procesamiento

gráfico (GPU) que mejora el enfoque tradicional de ejecución hibrida CPU-GPU, puesto

que ofrece la misma precisión y mejora de acuerdo con la Tabla 5-1 los tiempos de cálculo

en aproximadamente un 45%. Además, al implementar un algoritmo de generación

aleatoria de sistemas eléctricos de potencia y solucionar el sistema aleatoriamente

generado con la metodología propuesta, se encuentra que a partir de cierto número de

subsistemas la metodología resulta ser más competente que el enfoque tradicional de

cálculo de transitorios electromagnéticos en la CPU.

Para cumplir el objetivo general, esta investigación satisfizo los objetivos específicos

identificados en la introducción, para ello se definió un esquema de particionamiento

gráfico y se evaluaron las condiciones de operación de sistemas eléctricos de potencia a

través del uso de Equivalentes de Thévenin Multi Área (MATE) tal como se presenta en

los capítulos 2, 3 y 4. Finalmente, mencionados esquemas de particionamiento fueron

utilizados para realizar el cálculo de transitorios de sistemas eléctricos de potencia a partir

de técnicas de computación paralela usando la arquitectura CUDA en los capítulos 5 y 6.

Con la implementación de los modelos equivalentes de Dommel en la metodología de los

Equivalentes de Thévenin Multi Área y en particular con el uso del modelo equivalente de

Page 88: Simulación de transitorios electromagnéticos de sistemas

70 Simulación de transitorios electromagnéticos mediante programación de GPUs

las líneas de transmisión, esta investigación realiza un valioso aporte, ya que esto permite

emular de manera más acertada las características eléctricas de los equipos y elementos

de los sistemas eléctricos de potencia en el cálculo de transitorios electromagnéticos. El

modelo de línea empleado corresponde al modelo ideal de línea de transmisión, sin

embargo, la metodología propuesta es aplicable a modelos más detallados.

La metodología propuesta nombrada GPU-O no solo mejora los tiempos de ejecución en

aproximadamente un 45% y un 18% respecto a las estrategias de simulación CPU-GPU-1

y CPU-GPU-2 respectivamente sino que también a partir de cierto número de subsistemas

demuestra ser más competente que la solución de transitorios electromagnéticos en la

CPU, tal como se muestra en la Figura 6-10.

En resumen, se ha propuesto una metodología en la cual los sistemas eléctricos de

potencia son divididos gráficamente, para ello se define que los subsistemas estarán

compuestos por elementos que pertenecen a la misma infraestructura eléctrica

(subestación, central de generación, cargas, entre otros) y se establece que las líneas de

transmisión constituirán los enlaces de la metodología MATE. Posteriormente, este

sistema dividido es representando a través de modelos equivalentes obtenidos a partir de

la regla trapezoidal de integración y es solucionado completamente en la GPU mediante

la aplicación de la arquitectura CUDA.

La metodología anterior, como se muestra en el capítulo 6 en la Figura 6-11, exhibe un

paralelismo manteniendo el tiempo de ejecución por sistema aproximadamente constante

a pesar del incremento en la cantidad de subsistemas del sistema eléctrico de potencia a

resolver. Este comportamiento le permite a la metodología propuesta tener un desempeño

superior comparado con la solución de transitorios electromagnéticos en la CPU mediante

el uso de MATLAB.

Se identifica como clave el uso de los modelos equivalentes de Dommel para la simulación

de transitorios los cuales además de permitir desacoplar los sistemas, permiten la

representación de los componentes de la red a través de elementos resistivos y fuentes de

corriente con valores históricos, evitando el uso de modelos que implican la utilización de

números complejos, reduciendo así la complejidad de la programación y el respectivo

tiempo de ejecución.

Page 89: Simulación de transitorios electromagnéticos de sistemas

Conclusiones y trabajos futuros 71

El desarrollo propuesto no incluye la simulación en tiempo real de sistemas eléctricos de

potencia, sin embargo, se estima que con el uso de unidades de procesamiento gráfico

GPUs especializadas, así como de los accesorios necesarios para conectar un controlador

o una protección real, la metodología propuesta puede ser empleada cumpliendo con las

restricciones de las simulaciones en tiempo real.

Se destaca que en la comparación del desempeño GPU vs CPU presentada en el

capítulo 6 se utilizó una unidad de procesamiento gráfico GPU GeForce GTX 1050 de

gama media. Esta tarjeta gráfica es pensada más para la ejecución de videojuegos que

para computación paralela; no obstante, a partir de cierta cantidad de subsistemas su uso

resultó ser más competente que el uso de unidades de procesamiento central CPU, Lo

cual evidencia que la metodología propuesta constituye una alternativa accesible

comparada con el uso de super computadores o RTS.

Se destaca que la cantidad de subsistemas a partir de la cual resulta más competente el

uso de la GPU que de la CPU puede ser reducido a medida que se utilicen GPUs más

especializadas.

7.2 Trabajos futuros

Se recomienda explorar la utilización de modelos de líneas de transmisión diferentes al

modelo de parámetros distribuidos.

A su vez, se identifica la posibilidad de que a partir de la metodología propuesta se

implementen simuladores de tiempo real para lo cual deberán utilizarse unidades de

procesamiento gráfico especializadas como la serie Tesla de NVIDIA.

Page 90: Simulación de transitorios electromagnéticos de sistemas
Page 91: Simulación de transitorios electromagnéticos de sistemas

A. Anexo 1: Código validación uso modelos equivalentes de Dommel

1. clear all 2. clc 3. R0=10; 4. E=1; 5. Zc=350; 6. tao=60/300000; 7. deltat=tao/15; 8. C=0.1*1e-6; 9. G=[1/R0+1/Zc 0;0 1/Zc+2*C/deltat]; 10. H=inv(G); 11. 12. %Condiciones iniciales considerando sistema relajado 13. 14. I1(1)=0; 15. I2(1)=0; 16. Ic(1)=0; 17. u1(1)=0; 18. u2(1)=0; 19. ic(1)=0; 20. i12(1)=0; 21. i21(1)=0; 22. 23. %Tiempo máximo de simulación y primer paso de tiempo 24. tmax=35e-3; 25. t=deltat; 26. i=1+1; 27. 28. 29. while(t<=tmax) 30. ttao=round((t-tao)/deltat+1); 31. tdel=round((t-deltat)/deltat+1); 32. if t-tao<0 33. I1(i)=0; 34. I2(i)=0; 35. Ic(i)=-(2*C/deltat*u2(tdel)+ic(tdel)); 36. b=H*[E/R0-I1(i) -I2(i)-Ic(i)]'; 37. u1(i)=b(1); 38. u2(i)=b(2); 39. ic(i)= 2*C/deltat*u2(i)+Ic(i); 40. i12(i)=1/R0*(E-u1(i)); 41. i21(i)=-ic(i); 42. else 43. I1(i)=-(u2(ttao)/Zc+i21(ttao));

Page 92: Simulación de transitorios electromagnéticos de sistemas

74 Simulación de transitorios electromagnéticos mediante programación de GPUs

44. I2(i)=-(u1(ttao)/Zc+i12(ttao)); 45. Ic(i)=-(2*C/deltat*u2(tdel)+ic(tdel)); 46. b=H*[E/R0-I1(i) -I2(i)-Ic(i)]'; 47. u1(i)=b(1); 48. u2(i)=b(2); 49. ic(i)= 2*C/deltat*u2(i)+Ic(i); 50. i12(i)=1/R0*(E-u1(i)); 51. i21(i)=-ic(i); 52. 53. end 54. 55. %Actualización de parámetros 56. i=i+1; 57. t=t+deltat; 58. 59. end 60. %Se gráfican los resultados

61. plot([0:deltat:t-deltat],u2)

Page 93: Simulación de transitorios electromagnéticos de sistemas

B. Anexo 2: Código implementación MATE + Dommel

1. %MATE+DOMMEL+LÍNEA DE TRANSMISIÓN

2. 3. %Se usa una sola línea como enlace entre sistema A y sistema B

4. 5. %Se define el valor de las variables de cada subsistema, así como de la

6. %líneas de interconexión. 7. clear all

8. clc 9.

10. %Sistema A Conformado por resistencias 11. Ra12=20;

12. Ra23=10; 13. Ra34=2.5;

14. Ra14=5; 15. Ra4=2;

16. %Se calculan admitancias del sistema A 17. Ga12=1/Ra12;

18. Ga23=1/Ra23; 19. Ga34=1/Ra34;

20. Ga14=1/Ra14; 21. Ga4=1/Ra4;

22. 23. %Sistema B Conformado por resistencias

24. Rb12=7; 25. Rb23=5;

26. Rb34=2; 27. Rb14=10;

28. Rb4=8; 29. %Se calculan admitancias del sistema B

30. Gb12=1/Rb12; 31. Gb23=1/Rb23;

32. Gb34=1/Rb34; 33. Gb14=1/Rb14;

34. Gb4=1/Rb4; 35.

36. %Línea 37. long=60; %km

38. Zc=200; 39. vel=300000;

40. tao=long/vel; 41. deltat=tao/10;

42. tmax=35e-3; %tiempo máximo de simulación

Page 94: Simulación de transitorios electromagnéticos de sistemas

76 Simulación de transitorios electromagnéticos mediante programación de GPUs

43. Za1=Zc; 44. Za2=Zc;

45. 46. %Se definen las matrices Ybus respectivas, A y B, como si los sistemas A y

47. %B estuvieran separados

48. A=[Ga12+Ga14 -Ga12 0 -Ga14;-Ga12 Ga12+Ga23 -Ga23 0;0 -Ga23 Ga23+Ga34 -Ga34;-Ga14 0 -Ga34 Ga14+Ga34+Ga4]; %Matriz de admitancia sistema A

49. B=[Gb12+Gb14 -Gb12 0 -Gb14;-Gb12 Gb12+Gb23 -Gb23 0;0 -Gb23 Gb23+Gb34 -Gb34;-Gb14 0 -Gb34 Gb14+Gb34+Gb4];%Matriz de admitancia sistema B

50. 51. %Se define la matriz de enlace Z

52. Z=[Za1 0;0 Za2]; 53.

54. %Se definen matrices de inyección 55. p=[0 0 ;0 0;1 0 ;0 0]; %asociado a sistema A

56. q=[0 -1 ;0 0;0 0 ;0 0]; %asociado a sistema B 57.

58. a=inv(A)*p; 59. b=inv(B)*q;

60. 61. %Se define zalpha

62. Zalpha=p'*a+q'*b+Z; 63.

64. k=1; %Contador de posiciones para almacenar los datos 65. t=0; %Se inicia el tiempo

66. U_A3(k)=0; %Sistema inicialmente relajado 67. U_B1(k)=0;

68. t=t+deltat; 69. k=k+1;

70. 71. tic

72. while (t<=tmax) 73. ttao=round((t-tao)/deltat+1);

74. tdel=round((t-deltat)/deltat+1); 75. if t< 100*deltat

76. ramp(k)=t/(100*deltat)*1000; 77. else

78. ramp(k)=0; 79. end

80. if t-tao<0 %considerando el tiempo de viaje de la línea 81. I1(k)=0;

82. I2(k)=0; 83. else

84. I1(k)=-(U_B1(ttao)/Zc+i21(ttao)); 85. I2(k)=-(U_A3(ttao)/Zc+i12(ttao));

86. 87. end

88. 89. Ia=[ramp(k) 0 -I1(k) 0]'; %matriz de inyección sistema A

90. Ib=[-I2(k) 0 0 0]'; %matriz de inyección sistema B 91.

92. %Se determinan las tensiones de los equivalentes: 93. Ea=inv(A)*Ia;

94. Eb=inv(B)*Ib; 95. %Con las anteriores corrientes se determina la tensión asociada a

l enlace

96. %Ealpha

97. Ealpha=p'*Ea+q'*Eb; 98. %Se halla la corriente de los enlaces

99. Ialpha=inv(Zalpha)*Ealpha;

Page 95: Simulación de transitorios electromagnéticos de sistemas

Anexo B. Código implementación MATE + Dommel 77

100.

101. %Con la corriente de los enlaces se actualizan las tensione

s de

102. %los enlaces

103. Eanuevo=inv(A)*(Ia-p*Ialpha);

104. Ebnuevo=inv(B)*(Ib-q*Ialpha);

105.

106. U_A3(k)=Eanuevo(3);

107. U_B1(k)=Ebnuevo(1);

108.

109. %Con Eanuevo usando dommel se halla la corriente de las lín

eas

110. i12(k)=U_A3(k)/Zc+I1(k);

111. i21(k)=U_B1(k)/Zc+I2(k);

112.

113. %Se actualiza contador y tiempo

114. k=k+1;

115. t=t+deltat;

116.

117.

118. end

119. toc %Se detiene conteo de tiempo de cálculo

120. %Se gráfican los resultados

121. figure(1)

122. plot([0:deltat:t],U_B1)

123. title('Voltaje (V) vs Tiempo (s) Nodo 1 -Sistema B')

124. xlabel('Tiempo (s)') % x-axis label

125. ylabel('Voltaje (V)') % y-axis label

126. figure(2)

127. plot([0:deltat:t],U_A3)

128. title('Voltaje (V) vs Tiempo (s) Nodo 3 - Sistema A')

129. xlabel('Tiempo (s)') % x-axis label

130. ylabel('Voltaje (V)') % y-axis label

131. figure(3)

132. plot([0:deltat:t],ramp)

133. title('Corriente(A) vs Tiempo (s) -Iramp')

134. xlabel('Tiempo (s)') % x-axis label

135. ylabel('Corriente (A)') % y-axis label

Page 96: Simulación de transitorios electromagnéticos de sistemas

C. Anexo 3: Código computación paralela metodología CPU-GPU-1

1. #include <iostream> 2. #include <cmath> 3. #include <fstream> 4. #include "cuda.h" 5. #include "math.h" 6. #include <cstdio> 7. #include <chrono> 8. 9. 10. #define M 4 //M es el número de nodos de los subsistemas 11. #define N 6 //N es el número de enlaces entre los subsistemas, son 3 enla

ces pero por cada enlace es como si fueran 6

12. using namespace std; 13. using namespace std::chrono; 14. 15. __global__ void func1(double *A, double *B, double *C, int Col, int Row)

//Col y Row hacen alusión a la matriz que se esta multiplicando

16. 17. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 18. double tmp = 0; 19. if (ROW < Row) //Multiplicación matriz vector siendo B el vector de

orden Col

20. for (int i = 0; i < Col; i++) 21. tmp += A[ROW * Col + i] * B[i]; 22. 23. 24. 25. C[ROW] = tmp; /*Por la forma como se linealiza la matriz*/ 26. 27. 28. __global__ void func2(double *A, double *B, double *C, double *D, double *

E, double *F, double *G, int Col, int Row)

29. 30. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 31. double tmp = 0; 32. 33. 34. if (ROW < Row) 35. for (int i = 0; i < Col; i++) 36. tmp += A[ROW * Col + i] * B[i] + C[ROW * Col + i] * D[i] + E[R

OW * Col + i] * F[i];

37. 38. 39. 40. G[ROW] = tmp; 41.

Page 97: Simulación de transitorios electromagnéticos de sistemas

Anexo C. Código computación paralela metodología CPU-GPU 1 79

42. 43. __global__ void func3(double *A, double *B, double *C, double *D, int Row,

int Col)

44. 45. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 46. double tmp = 0; 47. if (ROW < Row) 48. for (int i = 0; i < Col; i++) 49. tmp += A[ROW * Col + i] * B[i]; 50. 51. 52. 53. D[ROW] = C[ROW] - tmp; /*Por la forma como se linealiza la matriz*/ 54. //printf("\n C = %f+%f i", C[ROW].x, C[ROW].y);

55. 56. 57. int main(void) 58. double Ea[M], Eb[M], Ec[M], Ealpha[N]; 59. double Ialpha[N], Ianuevo[M], Ibnuevo[M], Icnuevo[M], Eanuevo[M], Ebnu

evo[M], Ecnuevo[M];

60. double *dEa, *dEb, *dEc, *dInvA, *dInvB, *dInvC, *dIa, *dIb, *dIc, *dEalpha, *dptrans, *dqtrans, *drtrans, *dIalpha, *dinvZa, *dp, *dq, *dr, *dI

anuevo, *dIbnuevo, *dIcnuevo, *dEanuevo, *dEbnuevo, *dEcnuevo;

61. 62. 63. //Definición matrices inversas 64. double invA[M*M] = 0; 65. double invB[M*M] = 0; 66. double invC[M*M] = 0; 67. 68. ifstream archivo_invA; 69. archivo_invA.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trabajo

con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Mate3_matl

ab\\invA.txt");

70. 71. //Comprobación de errores en apertura del archivo 72. if (!archivo_invA.is_open()) 73. cout << "Error del archivo1" << endl; 74. 75. 76. for (int i = 0; i < M*M; i++) 77. archivo_invA >> invA[i]; 78. 79. 80. archivo_invA.close(); 81. 82. ifstream archivo_invB; 83. archivo_invB.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trabajo

con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Mate3_matl

ab\\invB.txt");

84. 85. //Comprobación de errores en apertura del archivo 86. if (!archivo_invB.is_open()) 87. cout << "Error del archivo2" << endl; 88. 89. 90. for (int i = 0; i < M*M; i++) 91. archivo_invB >> invB[i]; 92.

Page 98: Simulación de transitorios electromagnéticos de sistemas

80 Simulación de transitorios electromagnéticos mediante programación de GPUs

93. 94. archivo_invB.close(); 95. 96. 97. ifstream archivo_invC; 98. archivo_invC.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trabajo

con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Mate3_matl

ab\\invC.txt");

99. 100. //Comprobación de errores en apertura del archivo

101. if (!archivo_invC.is_open())

102. cout << "Error del archivo3" << endl;

103.

104.

105. for (int i = 0; i < M*M; i++)

106. archivo_invC >> invC[i];

107.

108.

109. archivo_invC.close();

110.

111. /*for (int i = 0; i < M*M; i++)

112. cout<<invB[i]<<endl;

113. */

114.

115.

116. //Definición parámetros de líneas

117. double delta[3];

118. //línea 1

119. double Zc1 = 200;

120. double Zc2 = Zc1;

121. double long1 = 60;

122. double tao1 = long1 / 300000;

123. delta[0] = tao1 / 10;

124. //línea 2

125. double Zc3 = 150;

126. double Zc4 = Zc3;

127. double long2 = 40;

128. double tao2 = long2 / 300000;

129. delta[1] = tao2 / 10;

130. //línea 3

131. double Zc5 = 180;

132. double Zc6 = Zc5;

133. double long3 = 20;

134. double tao3 = long3 / 300000;

135. delta[2] = tao3 / 10; //Ojo los vectores comienzan desde cero.

136.

137. double deltat = delta[0];

138. //printf("Deltat antes= %f \n", deltat);

139.

140. for (int i = 1; i < 3; i++)

141. if (delta[i] < deltat)

142. deltat = delta[i];

143.

144.

145. //printf("Deltat= %f \n", deltat);

146. //cout << "deltat= " << deltat << "\n";

147.

148. //Inicialización parámetro de tiempo

149. double t = 0;

150. int k = 0; //Inicialización parámetro de posición.

151. size_t kmax = ceil(0.035 / deltat) * sizeof(double);

Page 99: Simulación de transitorios electromagnéticos de sistemas

Anexo C. Código computación paralela metodología CPU-GPU 1 81

152. //printf("/n máximo número de pasos Kmax = %d \n", kmax);

153.

154.

155. double *I1, *I2, *I3, *I4, *I5, *I6, *U_A2, *U_B1, *i21, *i12, *

U_B3, *U_C2, *U_A3, *U_C1, *ic2, *ib3, *ic1, *ia3, *t1;

156. I1 = (double *)malloc(kmax);

157. I2 = (double *)malloc(kmax);

158. I3 = (double *)malloc(kmax);

159. I4 = (double *)malloc(kmax);

160. I5 = (double *)malloc(kmax);

161. I6 = (double *)malloc(kmax);

162. U_A2 = (double *)malloc(kmax);

163. U_B1 = (double *)malloc(kmax);

164. i21 = (double *)malloc(kmax);

165. i12 = (double *)malloc(kmax);

166. t1 = (double *)malloc(kmax);

167. U_A2[0] = 0;

168. U_B1[0] = 0;

169. i12[0] = 0;

170. i21[0] = 0;

171. I1[0] = 0;

172. I2[0] = 0;

173. I3[0] = 0;

174. I4[0] = 0;

175. I5[0] = 0;

176. I6[0] = 0;

177. t1[0] = 0;

178.

179. U_C2 = (double *)malloc(kmax);

180. U_B3 = (double *)malloc(kmax);

181. ic2 = (double *)malloc(kmax); //relacionadas con línea 2

182. ib3 = (double *)malloc(kmax); //relacionadas con línea 2

183. U_C2[0] = 0;

184. U_B3[0] = 0;

185. ic2[0] = 0;

186. ib3[0] = 0;

187.

188. U_C1 = (double *)malloc(kmax);

189. U_A3 = (double *)malloc(kmax);

190. ic1 = (double *)malloc(kmax); //relacionadas con línea 3

191. ia3 = (double *)malloc(kmax); //relacionadas con línea 3

192. U_C1[0] = 0;

193. U_A3[0] = 0;

194. ic1[0] = 0;

195. ia3[0] = 0;

196.

197.

198. //Definición matriz inversa Zalpha

199. double invZa[N*N] = 0;

200.

201. ifstream archivo_invZalpha;

202. archivo_invZalpha.open("C:\\Users\\Quartas\\Google Drive\\Maestr

ía\\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\

\Mate3_matlab\\invZalpha.txt");

203.

204. //Comprobación de errores en apertura del archivo

205. if (!archivo_invZalpha.is_open())

206. cout << "Error del archivo4" << endl;

207.

208.

Page 100: Simulación de transitorios electromagnéticos de sistemas

82 Simulación de transitorios electromagnéticos mediante programación de GPUs

209. for (int i = 0; i < N*N; i++)

210. archivo_invZalpha >> invZa[i];

211.

212.

213. archivo_invZalpha.close();

214.

215. //definición matrices de relación traspuestas

216.

217. double ptrans[M*N] = 0;

218. double qtrans[M*N] = 0;

219. double rtrans[M*N] = 0;

220.

221. ifstream archivo_pprima;

222. archivo_pprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Ma

te3_matlab\\pprima.txt");

223.

224. //Comprobación de errores en apertura del archivo

225. if (!archivo_pprima.is_open())

226. cout << "Error del archivo5" << endl;

227.

228.

229. for (int j = 0; j < N*M; j++)

230. archivo_pprima >> ptrans[j];

231.

232.

233.

234. archivo_pprima.close();

235.

236.

237. ifstream archivo_qprima;

238. archivo_qprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Ma

te3_matlab\\qprima.txt");

239.

240. //Comprobación de errores en apertura del archivo

241. if (!archivo_qprima.is_open())

242. cout << "Error del archivo6" << endl;

243.

244.

245. for (int j = 0; j < N*M; j++)

246. archivo_qprima >> qtrans[j];

247.

248.

249.

250. archivo_qprima.close();

251.

252. ifstream archivo_rprima;

253. archivo_rprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Ma

te3_matlab\\rprima.txt");

254.

255. //Comprobación de errores en apertura del archivo

256. if (!archivo_rprima.is_open())

257. cout << "Error del archivo7" << endl;

258.

259.

260. for (int j = 0; j < N*M; j++)

261. archivo_rprima >> rtrans[j];

262.

263.

Page 101: Simulación de transitorios electromagnéticos de sistemas

Anexo C. Código computación paralela metodología CPU-GPU 1 83

264.

265. archivo_rprima.close();

266.

267.

268. //Definición Matriz p, matriz de orden MxN, asociada a los enlac

es del sistema A.

269. double p[M*N] = 0;

270.

271. //Definición Matriz q, matriz de orden MxN, asociada a los enlac

es del sistema B.

272. double q[M*N] = 0;

273.

274. //Definición Matriz r, matriz de orden MxN, asociada a los enlac

es del sistema C.

275. double r[M*N] = 0 ;

276.

277. ifstream archivo_p;

278. archivo_p.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Mate3_m

atlab\\p.txt");

279.

280. //Comprobación de errores en apertura del archivo

281. if (!archivo_p.is_open())

282. cout << "Error del archivo8" << endl;

283.

284.

285. for (int j = 0; j < M*N; j++)

286. archivo_p >> p[j];

287.

288.

289.

290. archivo_p.close();

291.

292. ifstream archivo_q;

293. archivo_q.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Mate3_m

atlab\\q.txt");

294.

295. //Comprobación de errores en apertura del archivo

296. if (!archivo_q.is_open())

297. cout << "Error del archivo9" << endl;

298.

299.

300. for (int j = 0; j < M*N; j++)

301. archivo_q >> q[j];

302.

303.

304.

305. archivo_q.close();

306.

307. ifstream archivo_r;

308. archivo_r.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3_base\\Mate3_m

atlab\\r.txt");

309.

310. //Comprobación de errores en apertura del archivo

311. if (!archivo_r.is_open())

312. cout << "Error del archivo10" << endl;

313.

314.

Page 102: Simulación de transitorios electromagnéticos de sistemas

84 Simulación de transitorios electromagnéticos mediante programación de GPUs

315. for (int j = 0; j < M*N; j++)

316. archivo_r >> r[j];

317.

318.

319.

320. archivo_r.close();

321.

322.

323. cudaMalloc(&dEa, M * sizeof(double));

324. cudaMalloc(&dEb, M * sizeof(double));

325. cudaMalloc(&dEc, M * sizeof(double));

326. cudaMalloc(&dInvA, M*M * sizeof(double));

327. cudaMalloc(&dInvB, M*M * sizeof(double));

328. cudaMalloc(&dInvC, M*M * sizeof(double));

329. cudaMalloc(&dIa, M * sizeof(double));

330. cudaMalloc(&dIb, M * sizeof(double));

331. cudaMalloc(&dIc, M * sizeof(double));

332.

333.

334. cudaMemcpy(dInvA, invA, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

335. cudaMemcpy(dInvB, invB, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

336. cudaMemcpy(dInvC, invC, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

337.

338.

339. cudaMalloc(&dEalpha, N * sizeof(double));

340. cudaMalloc(&dptrans, (N*M) * sizeof(double));

341. cudaMalloc(&dqtrans, (N*M) * sizeof(double));

342. cudaMalloc(&drtrans, (N*M) * sizeof(double));

343. cudaMemcpy(dptrans, ptrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

344. cudaMemcpy(dqtrans, qtrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

345. cudaMemcpy(drtrans, rtrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

346.

347.

348. cudaMalloc(&dIalpha, N * sizeof(double));

349. cudaMalloc(&dinvZa, (N*N) * sizeof(double));

350. cudaMemcpy(dinvZa, invZa, (N*N) * sizeof(double), cudaMemcpyHost

ToDevice);

351.

352.

353. cudaMalloc(&dp, (M*N) * sizeof(double));

354. cudaMalloc(&dq, (M*N) * sizeof(double));

355. cudaMalloc(&dr, (M*N) * sizeof(double));

356. cudaMalloc(&dIanuevo, (M) * sizeof(double));

357. cudaMalloc(&dIbnuevo, (M) * sizeof(double));

358. cudaMalloc(&dIcnuevo, (M) * sizeof(double));

359. cudaMemcpy(dp, p, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

360. cudaMemcpy(dq, q, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

361. cudaMemcpy(dr, r, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

362.

363. cudaMalloc(&dEanuevo, (M) * sizeof(double));

364. cudaMalloc(&dEbnuevo, (M) * sizeof(double));

365. cudaMalloc(&dEcnuevo, (M) * sizeof(double));

Page 103: Simulación de transitorios electromagnéticos de sistemas

Anexo C. Código computación paralela metodología CPU-GPU 1 85

366.

367.

368. printf("Primer valor \n");

369. //time_t start, end;

370. //time(&start);

371. auto start = high_resolution_clock::now();

372. t = t + deltat;

373. k = k + 1;

374. t1[k] = t;

375.

376.

377. while (t < 0.035) //35ms es el tiempo máximo de cálculo

378.

379. //indicadores de posición para los valores al

macenados

380. int ttao1 = int((t - tao1) / deltat);

381. int ttao2 = int((t - tao2) / deltat);

382. int ttao3 = int((t - tao3) / deltat);

383.

384.

385.

386.

387. //printf("El tiempo ttao2 es %d \n", int(floor(ttao2)));

388.

389. if ((t - tao1) < 0)

390. I1[k] = 0;

391. I2[k] = 0;

392.

393. else

394. I1[k] = -(U_B1[ttao1] / Zc1 + i21[ttao1]);

395. I2[k] = -(U_A2[ttao1] / Zc1 + i12[ttao1]);

396.

397.

398.

399. if ((t - tao2) < 0)

400. I3[k] = 0;

401. I4[k] = 0;

402.

403. else

404.

405. I3[k] = -(U_C2[ttao2] / Zc3 + ic2[ttao2]);

406. I4[k] = -(U_B3[ttao2] / Zc3 + ib3[ttao2]);

407.

408.

409.

410. if ((t - tao3) < 0)

411. I5[k] = 0;

412. I6[k] = 0;

413.

414. else

415.

416. I5[k] = -(U_C1[ttao3] / Zc5 + ic1[ttao3]);

417. I6[k] = -(U_A3[ttao3] / Zc5 + ia3[ttao3]);

418.

419.

420.

421. //Iramp

422. double ramp;

423. if (t < 100 * deltat)

424. ramp = t / (100 * deltat) * 1000;

Page 104: Simulación de transitorios electromagnéticos de sistemas

86 Simulación de transitorios electromagnéticos mediante programación de GPUs

425.

426. else

427. ramp = 0;

428.

429.

430. //Con I1, I2..., I6 puedo hallar las tensiones de los sistem

as Ia, Ib, Ic

431.

432.

433. double Ia[M] = ramp, -I1[k], -I5[k], 0 ;

434. double Ib[M] = -I2[k], 0, -I3[k], 0 ;

435. double Ic[M] = -I6[k], -I4[k], 0, 0 ;

436.

437.

438.

439. cudaMemcpy(dIa, Ia, M * sizeof(double), cudaMemcpyHostToDevi

ce);

440. cudaMemcpy(dIb, Ib, M * sizeof(double), cudaMemcpyHostToDevi

ce);

441. cudaMemcpy(dIc, Ic, M * sizeof(double), cudaMemcpyHostToDevi

ce);

442.

443.

444. dim3 blocksPerGrid(1, 1, 1);

445. dim3 threadsPerBlock(M, 1, 1);

446.

447. //Cálculo de Ea, Eb y Ec en streams diferentes

448.

449. func1 << <blocksPerGrid, threadsPerBlock >> >(dInvA, dIa, dE

a, M, M);

450. //cudaThreadSynchronize();

451. func1 << <blocksPerGrid, threadsPerBlock >> >(dInvB, dIb, dE

b, M, M);

452. //cudaThreadSynchronize();

453. func1 << <blocksPerGrid, threadsPerBlock >> >(dInvC, dIc, dE

c, M, M);

454. //cudaThreadSynchronize();

455.

456. cudaDeviceSynchronize();

457.

458. //Cálculo de Ealpha

459.

460. threadsPerBlock.x = N;

461.

462. func2 << <blocksPerGrid, threadsPerBlock >> >(dptrans, dEa,

dqtrans, dEb, drtrans, dEc, dEalpha, M, N);

463. //cudaThreadSynchronize();

464. cudaDeviceSynchronize();

465.

466.

467. //Cálculo de Ialpha

468.

469. func1 << <blocksPerGrid, threadsPerBlock >> >(dinvZa, dEalph

a, dIalpha, N, N);

470. //cudaThreadSynchronize();

471. cudaDeviceSynchronize();

472.

473. //Cálculo de corrientes de inyección nuevas

474.

475. threadsPerBlock.x = M;

476.

Page 105: Simulación de transitorios electromagnéticos de sistemas

Anexo C. Código computación paralela metodología CPU-GPU 1 87

477.

478. func3 << <blocksPerGrid, threadsPerBlock >> >(dp, dIalpha, d

Ia, dIanuevo, M, N);

479. //cudaThreadSynchronize();

480. func3 << <blocksPerGrid, threadsPerBlock >> >(dq, dIalpha, d

Ib, dIbnuevo, M, N);

481. //cudaThreadSynchronize();

482. func3 << <blocksPerGrid, threadsPerBlock >> >(dr, dIalpha, d

Ic, dIcnuevo, M, N);

483. //cudaThreadSynchronize();

484.

485. cudaDeviceSynchronize();

486.

487. //Cálculo de tensiones nodales nuevas

488.

489. func1 << <blocksPerGrid, threadsPerBlock >> >(dInvA, dIanuev

o, dEanuevo, M, M);

490. //cudaThreadSynchronize();

491. func1 << <blocksPerGrid, threadsPerBlock >> >(dInvB, dIbnuev

o, dEbnuevo, M, M);

492. //cudaThreadSynchronize();

493. func1 << <blocksPerGrid, threadsPerBlock >> >(dInvC, dIcnuev

o, dEcnuevo, M, M);

494. //cudaThreadSynchronize();

495. cudaDeviceSynchronize();

496.

497. cudaMemcpy(Eanuevo, dEanuevo, (M) * sizeof(double), cudaMemc

pyDeviceToHost);

498. cudaMemcpy(Ebnuevo, dEbnuevo, (M) * sizeof(double), cudaMemc

pyDeviceToHost);

499. cudaMemcpy(Ecnuevo, dEcnuevo, (M) * sizeof(double), cudaMemc

pyDeviceToHost);

500. //cudaDeviceSynchronize();

501.

502. //Actualización de parámetros

503.

504. U_B1[k] = Ebnuevo[0];

505. i21[k] = U_B1[k] / Zc2 + I2[k];

506. U_A2[k] = Eanuevo[1];

507. i12[k] = U_A2[k] / Zc1 + I1[k];

508. U_B3[k] = Ebnuevo[2];

509. ib3[k] = U_B3[k] / Zc3 + I3[k];

510. U_C2[k] = Ecnuevo[1];

511. ic2[k] = U_C2[k] / Zc4 + I4[k];

512. U_A3[k] = Eanuevo[2];

513. ia3[k] = U_A3[k] / Zc5 + I5[k];

514. U_C1[k] = Ecnuevo[0];

515. ic1[k] = U_C1[k] / Zc6 + I6[k];

516.

517.

518. t += deltat;

519. k = k + 1;

520. t1[k] = t;

521.

522.

523. auto stop = high_resolution_clock::now();

524. auto duration = duration_cast<microseconds>(stop - start);

525.

526. FILE *fp;

527. fp = fopen("tension.txt", "w");

Page 106: Simulación de transitorios electromagnéticos de sistemas

88 Simulación de transitorios electromagnéticos mediante programación de GPUs

528.

529. for (int i = 0; i < k-1; i++)

530. fprintf(fp, "%f %f %f %f %f %f \n", U_A2[i], U_B1[i], U_B3[i

], U_C2[i], U_A3[i], U_C1[i]);

531.

532.

533.

534.

535. cout << " Tiempo de ejecucion " << duration.count() << " microse

conds" << endl;

536. printf("ultimo valor \n");

537. fclose(fp);

538. cout << deltat << endl;

539. return 0;

540.

Page 107: Simulación de transitorios electromagnéticos de sistemas

D. Anexo 4: Código computación paralela metodología CPU-GPU 2.

1. #include <iostream> 2. #include <cmath> 3. #include <fstream> 4. #include "cuda.h" 5. #include "math.h" 6. #include <cstdio> 7. #include <chrono> 8. 9. 10. #define M 4 //M es el número de nodos de los subsistemas 11. #define N 6 //N es el número de enlaces entre los subsistemas 12. using namespace std; 13. using namespace std::chrono; 14. 15. __global__ void func1(double *A, double *B, double *C, int Col, int Row)

//Col y Row hacen alusión a la matriz que se esta multiplicando

16. 17. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 18. double tmp = 0; 19. if (ROW < Row) //Multiplicación matriz vector siendo B el vector de

orden Col

20. for (int i = 0; i < Col; ++i) 21. tmp += A[ROW * Col + i] * B[i]; 22. 23. 24. 25. C[ROW] = tmp; /*Por la forma como se linealiza la matriz*/ 26. 27. 28. __global__ void func2(double *A, double *B, double *C, double *D, double *

E, double *F, double *G, int Col, int Row)

29. 30. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 31. double tmp = 0; 32. 33. 34. if (ROW < Row) 35. for (int i = 0; i < Col; ++i) 36. tmp += A[ROW * Col + i] * B[i] + C[ROW * Col + i] * D[i] + E[R

OW * Col + i] * F[i];

37. 38. 39. 40. G[ROW] = tmp; 41. 42.

Page 108: Simulación de transitorios electromagnéticos de sistemas

90 Simulación de transitorios electromagnéticos mediante programación de GPUs

43. __global__ void func3(double *A, double *B, double *C, double *D, int Row, int Col)

44. 45. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 46. double tmp = 0; 47. if (ROW < Row) 48. for (int i = 0; i < Col; ++i) 49. tmp += A[ROW * Col + i]* B[i]; 50. 51. 52. 53. D[ROW] = C[ROW]-tmp; /*Por la forma como se linealiza la matriz*/ 54. //printf("\n C = %f+%f i", C[ROW].x, C[ROW].y); 55. 56. 57. int main(void) 58. 59. double Eanuevo[M], Ebnuevo[M], Ecnuevo[M]; 60. double *dEa, *dEb, *dEc, *dInvA, *dInvB, *dInvC, *dIa, *dIb, *dIc, *dE

alpha, *dptrans, *dqtrans, *drtrans, *dIalpha, *dinvZa, *dp, *dq, *dr, *dI

anuevo, *dIbnuevo, *dIcnuevo, *dEanuevo, *dEbnuevo, *dEcnuevo;

61. 62. 63. //Definición matrices inversas 64. double invA[M*M] = 0 ; 65. double invB[M*M] = 0 ; 66. double invC[M*M] = 0 ; 67. 68. 69. ifstream archivo_invA; 70. archivo_invA.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trabajo

con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimizado\\Mate

3_opt MATLAB\\invA.txt");

71. 72. //Comprobación de errores en apertura del archivo 73. if (!archivo_invA.is_open()) 74. cout << "Error del archivo1" << endl; 75. 76. 77. for (int i = 0; i < M*M; i++) 78. archivo_invA >> invA[i]; 79. 80. 81. archivo_invA.close(); 82. 83. ifstream archivo_invB; 84. archivo_invB.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trabajo

con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimizado\\Mate

3_opt MATLAB\\invB.txt");

85. 86. //Comprobación de errores en apertura del archivo 87. if (!archivo_invB.is_open()) 88. cout << "Error del archivo2" << endl; 89. 90. 91. for (int i = 0; i < M*M; i++) 92. archivo_invB >> invB[i]; 93. 94. 95. archivo_invB.close(); 96.

Page 109: Simulación de transitorios electromagnéticos de sistemas

Anexo D. Código computación paralela metodología CPU-GPU 2 91

97. 98. ifstream archivo_invC; 99. archivo_invC.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trabajo

con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimizado\\Mate

3_opt MATLAB\\invC.txt");

100.

101. //Comprobación de errores en apertura del archivo

102. if (!archivo_invC.is_open())

103. cout << "Error del archivo3" << endl;

104.

105.

106. for (int i = 0; i < M*M; i++)

107. archivo_invC >> invC[i];

108.

109.

110. archivo_invC.close();

111.

112. //Definición parámetros de líneas

113. double delta[3];

114. //línea 1

115. double Zc1 = 200;

116. double Zc2 = Zc1;

117. double long1 = 60;

118. double tao1 = long1 / 300000;

119. delta[0] = tao1 / 10;

120. //línea 2

121. double Zc3 = 150;

122. double Zc4 = Zc3;

123. double long2 = 40;

124. double tao2 = long2 / 300000;

125. delta[1] = tao2 / 10;

126. //línea 3

127. double Zc5 = 180;

128. double Zc6 = Zc5;

129. double long3 = 20;

130. double tao3 = long3 / 300000;

131. delta[2] = tao3 / 10; //Ojo los vectores comienzan desde cero.

132.

133. double deltat = delta[0];

134. //printf("Deltat antes= %f \n", deltat);

135.

136. for (int i = 1; i < 3; i++)

137. if (delta[i] < deltat)

138. deltat = delta[i];

139.

140.

141. //printf("Deltat= %f \n", deltat);

142.

143. //Inicialización parámetro de tiempo

144. double t = 0;

145. int k = 0; //Inicialización parámetro de posición.

146. size_t kmax = ceil(0.035 / deltat) * sizeof(double);

147. //printf("/n máximo número de pasos Kmax = %f \n", ceil(0.035 /

deltat) );

148.

149. double *I1, *I2, *I3, *I4, *I5, *I6, *U_A2, *U_B1, *i21, *i12, *

U_B3, *U_C2, *U_A3, *U_C1, *ic2, *ib3, *ic1, *ia3, *t1;

150. I1 = (double *)malloc(kmax);

151. I2 = (double *)malloc(kmax);

152. I3 = (double *)malloc(kmax);

Page 110: Simulación de transitorios electromagnéticos de sistemas

92 Simulación de transitorios electromagnéticos mediante programación de GPUs

153. I4 = (double *)malloc(kmax);

154. I5 = (double *)malloc(kmax);

155. I6 = (double *)malloc(kmax);

156. U_A2 = (double *)malloc(kmax);

157. U_B1 = (double *)malloc(kmax);

158. i21 = (double *)malloc(kmax);

159. i12 = (double *)malloc(kmax);

160. t1 = (double *)malloc(kmax);

161. U_A2[0] = 0;

162. U_B1[0] = 0;

163. i12[0] = 0;

164. i21[0] = 0;

165. I1[0] = 0;

166. I2[0] = 0;

167. I3[0] = 0;

168. I4[0] = 0;

169. I5[0] = 0;

170. I6[0] = 0;

171. t1[0] = 0;

172.

173. U_C2 = (double *)malloc(kmax);

174. U_B3 = (double *)malloc(kmax);

175. ic2 = (double *)malloc(kmax); //relacionadas con línea 2

176. ib3 = (double *)malloc(kmax); //relacionadas con línea 2

177. U_C2[0] = 0;

178. U_B3[0] = 0;

179. ic2[0] = 0;

180. ib3[0] = 0;

181.

182. U_C1 = (double *)malloc(kmax);

183. U_A3 = (double *)malloc(kmax);

184. ic1 = (double *)malloc(kmax); //relacionadas con línea 3

185. ia3 = (double *)malloc(kmax); //relacionadas con línea 3

186. U_C1[0] = 0;

187. U_A3[0] = 0;

188. ic1[0] = 0;

189. ia3[0] = 0;

190.

191. //Definición matriz inversa Zalpha

192. double invZa[N*N] = 0;

193.

194. ifstream archivo_invZalpha;

195. archivo_invZalpha.open("C:\\Users\\Quartas\\Google Drive\\Maestr

ía\\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optim

izado\\Mate3_opt MATLAB\\invZalpha.txt");

196.

197. //Comprobación de errores en apertura del archivo

198. if (!archivo_invZalpha.is_open())

199. cout << "Error del archivo4" << endl;

200.

201.

202. for (int i = 0; i < N*N; i++)

203. archivo_invZalpha >> invZa[i];

204.

205.

206. archivo_invZalpha.close();

207.

208. //definición matrices de relación traspuestas

209.

210. double ptrans[M*N] = 0;

211. double qtrans[M*N] = 0;

Page 111: Simulación de transitorios electromagnéticos de sistemas

Anexo D. Código computación paralela metodología CPU-GPU 2 93

212. double rtrans[M*N] = 0;

213.

214. ifstream archivo_pprima;

215. archivo_pprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimiza

do\\Mate3_opt MATLAB\\pprima.txt");

216.

217. //Comprobación de errores en apertura del archivo

218. if (!archivo_pprima.is_open())

219. cout << "Error del archivo5" << endl;

220.

221.

222. for (int j = 0; j < N*M; j++)

223. archivo_pprima >> ptrans[j];

224.

225.

226.

227. archivo_pprima.close();

228.

229.

230. ifstream archivo_qprima;

231. archivo_qprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimiza

do\\Mate3_opt MATLAB\\qprima.txt");

232.

233. //Comprobación de errores en apertura del archivo

234. if (!archivo_qprima.is_open())

235. cout << "Error del archivo6" << endl;

236.

237.

238. for (int j = 0; j < N*M; j++)

239. archivo_qprima >> qtrans[j];

240.

241.

242.

243. archivo_qprima.close();

244.

245. ifstream archivo_rprima;

246. archivo_rprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimiza

do\\Mate3_opt MATLAB\\rprima.txt");

247.

248. //Comprobación de errores en apertura del archivo

249. if (!archivo_rprima.is_open())

250. cout << "Error del archivo7" << endl;

251.

252.

253. for (int j = 0; j < N*M; j++)

254. archivo_rprima >> rtrans[j];

255.

256.

257.

258. archivo_rprima.close();

259.

260.

261. //Definición Matriz p, matriz de orden MxN, asociada a los enlac

es del sistema A.

262. double p[M*N] = 0 ;

263.

Page 112: Simulación de transitorios electromagnéticos de sistemas

94 Simulación de transitorios electromagnéticos mediante programación de GPUs

264. //Definición Matriz q, matriz de orden MxN, asociada a los enlac

es del sistema B.

265. double q[M*N] = 0 ;

266.

267. //Definición Matriz r, matriz de orden MxN, asociada a los enlac

es del sistema C.

268. double r[M*N] = 0 ;

269.

270. ifstream archivo_p;

271. archivo_p.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimizado\\M

ate3_opt MATLAB\\p.txt");

272.

273. //Comprobación de errores en apertura del archivo

274. if (!archivo_p.is_open())

275. cout << "Error del archivo8" << endl;

276.

277.

278. for (int j = 0; j < M*N; j++)

279. archivo_p >> p[j];

280.

281.

282.

283. archivo_p.close();

284.

285. ifstream archivo_q;

286. archivo_q.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimizado\\M

ate3_opt MATLAB\\q.txt");

287.

288. //Comprobación de errores en apertura del archivo

289. if (!archivo_q.is_open())

290. cout << "Error del archivo9" << endl;

291.

292.

293. for (int j = 0; j < M*N; j++)

294. archivo_q >> q[j];

295.

296.

297.

298. archivo_q.close();

299.

300. ifstream archivo_r;

301. archivo_r.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\MATE3_optimizado\\M

ate3_opt MATLAB\\r.txt");

302.

303. //Comprobación de errores en apertura del archivo

304. if (!archivo_r.is_open())

305. cout << "Error del archivo10" << endl;

306.

307.

308. for (int j = 0; j < M*N; j++)

309. archivo_r >> r[j];

310.

311.

312.

313. archivo_r.close();

314.

315. cudaMalloc(&dEa, M * sizeof(double));

316. cudaMalloc(&dEb, M * sizeof(double));

Page 113: Simulación de transitorios electromagnéticos de sistemas

Anexo D. Código computación paralela metodología CPU-GPU 2 95

317. cudaMalloc(&dEc, M * sizeof(double));

318. cudaMalloc(&dInvA, M*M * sizeof(double));

319. cudaMalloc(&dInvB, M*M * sizeof(double));

320. cudaMalloc(&dInvC, M*M * sizeof(double));

321. cudaMalloc(&dIa, M * sizeof(double));

322. cudaMalloc(&dIb, M * sizeof(double));

323. cudaMalloc(&dIc, M * sizeof(double));

324.

325.

326. cudaMemcpy(dInvA, invA, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

327. cudaMemcpy(dInvB, invB, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

328. cudaMemcpy(dInvC, invC, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

329.

330.

331. cudaMalloc(&dEalpha, N * sizeof(double));

332. cudaMalloc(&dptrans, (N*M) * sizeof(double));

333. cudaMalloc(&dqtrans, (N*M) * sizeof(double));

334. cudaMalloc(&drtrans, (N*M) * sizeof(double));

335. cudaMemcpy(dptrans, ptrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

336. cudaMemcpy(dqtrans, qtrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

337. cudaMemcpy(drtrans, rtrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

338.

339.

340. cudaMalloc(&dIalpha, N * sizeof(double));

341. cudaMalloc(&dinvZa, (N*N) * sizeof(double));

342. cudaMemcpy(dinvZa, invZa, (N*N) * sizeof(double), cudaMemcpyHost

ToDevice);

343.

344.

345. cudaMalloc(&dp, (M*N) * sizeof(double));

346. cudaMalloc(&dq, (M*N) * sizeof(double));

347. cudaMalloc(&dr, (M*N) * sizeof(double));

348. cudaMalloc(&dIanuevo, (M) * sizeof(double));

349. cudaMalloc(&dIbnuevo, (M) * sizeof(double));

350. cudaMalloc(&dIcnuevo, (M) * sizeof(double));

351. cudaMemcpy(dp, p, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

352. cudaMemcpy(dq, q, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

353. cudaMemcpy(dr, r, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

354.

355. cudaMalloc(&dEanuevo, (M) * sizeof(double));

356. cudaMalloc(&dEbnuevo, (M) * sizeof(double));

357. cudaMalloc(&dEcnuevo, (M) * sizeof(double));

358.

359.

360. //Se crean los streams necesarios para ejecutar el kernel parale

lamente

361. cudaStream_t stream[3];

362. cudaStreamCreate(&stream[0]);

363. cudaStreamCreate(&stream[1]);

364. cudaStreamCreate(&stream[2]);

365.

Page 114: Simulación de transitorios electromagnéticos de sistemas

96 Simulación de transitorios electromagnéticos mediante programación de GPUs

366. t = t + deltat;

367. k = k + 1;

368. t1[k] = t;

369.

370. dim3 blocksPerGrid(1, 1, 1);

371. dim3 threadsPerBlock(M, 1, 1);

372.

373. printf("Primer valor \n");

374. auto start = high_resolution_clock::now();

375.

376. while (t < 0.035) //35ms es el tiempo máximo de cálculo

377.

378. //indicadores de posición para los valores almacenados

379. int ttao1 = int((t - tao1) / deltat);

380. int ttao2 = int((t - tao2) / deltat);

381. int ttao3 = int((t - tao3) / deltat);

382.

383. //printf("El tiempo ttao2 es %d \n", int(floor(ttao2)));

384.

385. if ((t - tao1) < 0)

386. I1[k] =0;

387. I2[k] =0;

388.

389. else

390.

391. I1[k] = -(U_B1[ttao1] / Zc1 + i21[ttao1]);

392. I2[k] = -(U_A2[ttao1] / Zc1 + i12[ttao1]);

393.

394.

395.

396. if ((t - tao2) < 0)

397. I3[k] = 0;

398. I4[k] = 0;

399.

400. else

401.

402. I3[k] = -(U_C2[ttao2] / Zc3 + ic2[ttao2]);

403. I4[k] = -(U_B3[ttao2] / Zc3 + ib3[ttao2]);

404.

405.

406.

407. if ((t - tao3) < 0)

408. I5[k] = 0;

409. I6[k] = 0;

410.

411. else

412.

413. I5[k] = -(U_C1[ttao3] / Zc5 + ic1[ttao3]);

414. I6[k] = -(U_A3[ttao3] / Zc5 + ia3[ttao3]);

415.

416.

417. //Iramp

418. double ramp;

419. if (t < 100 * deltat)

420. ramp = t / (100 * deltat) * 1000;

421. //printf("El valor de la corriente es %f \n", ramp);

422.

423. else

424. ramp = 0;

425.

426.

Page 115: Simulación de transitorios electromagnéticos de sistemas

Anexo D. Código computación paralela metodología CPU-GPU 2 97

427. //Con I1, I2..., I6 puedo hallar las tensiones de los sistem

as Ia, Ib, Ic

428.

429. double Ia[M] = ramp, -I1[k], -I5[k], 0 ;

430. double Ib[M] = -I2[k], 0, -I3[k], 0 ;

431. double Ic[M] = -I6[k], -I4[k], 0, 0 ;

432.

433.

434.

435.

436. cudaMemcpyAsync(dIa, Ia, M * sizeof(double), cudaMemcpyHostT

oDevice, stream[0]);

437. cudaMemcpyAsync(dIb, Ib, M * sizeof(double), cudaMemcpyHostT

oDevice, stream[1]);

438. cudaMemcpyAsync(dIc, Ic, M * sizeof(double), cudaMemcpyHostT

oDevice, stream[2]);

439. cudaDeviceSynchronize();

440.

441.

442.

443. threadsPerBlock.x = M;

444.

445. //Cálculo de Ea, Eb y Ec en streams diferentes

446.

447. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dInvA, dIa, dEa, M, M);

448.

449. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >(

dInvB, dIb, dEb, M, M);

450.

451. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[2] >> >(

dInvC, dIc, dEc, M, M);

452.

453.

454. cudaDeviceSynchronize();

455.

456. //Cálculo de Ealpha

457.

458. threadsPerBlock.x = N;

459.

460. func2 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dptrans, dEa, dqtrans, dEb, drtrans, dEc, dEalpha, M, N);

461.

462.

463.

464. //Cálculo de Ialpha

465.

466. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dinvZa, dEalpha, dIalpha, N, N);

467. //cudaThreadSynchronize();

468. cudaDeviceSynchronize();

469.

470. //Cálculo de corrientes de inyección nuevas

471.

472. threadsPerBlock.x = M;

473.

474.

475. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dp, dIalpha, dIa, dIanuevo, M, N);

476.

Page 116: Simulación de transitorios electromagnéticos de sistemas

98 Simulación de transitorios electromagnéticos mediante programación de GPUs

477. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >(

dq, dIalpha, dIb, dIbnuevo, M, N);

478.

479. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[2] >> >(

dr, dIalpha, dIc, dIcnuevo, M, N);

480.

481.

482. //Cálculo de tensiones nodales nuevas

483.

484. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dInvA, dIanuevo, dEanuevo, M, M);

485. //cudaThreadSynchronize();

486. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >(

dInvB, dIbnuevo, dEbnuevo, M, M);

487. //cudaThreadSynchronize();

488. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[2] >> >(

dInvC, dIcnuevo, dEcnuevo, M, M);

489. //cudaThreadSynchronize();

490.

491.

492. cudaMemcpyAsync(Eanuevo, dEanuevo, (M) * sizeof(double), cud

aMemcpyDeviceToHost, stream[0]);

493. cudaMemcpyAsync(Ebnuevo, dEbnuevo, (M) * sizeof(double), cud

aMemcpyDeviceToHost, stream[1]);

494. cudaMemcpyAsync(Ecnuevo, dEcnuevo, (M) * sizeof(double), cud

aMemcpyDeviceToHost, stream[2]);

495. cudaDeviceSynchronize();

496.

497. U_B1[k] = Ebnuevo[0];

498. i21[k] = U_B1[k] / Zc2 + I2[k];

499. U_A2[k] = Eanuevo[1];

500. i12[k] = U_A2[k] / Zc1 + I1[k];

501. U_B3[k] = Ebnuevo[2];

502. ib3[k] = U_B3[k] / Zc3 + I3[k];

503. U_C2[k] = Ecnuevo[1];

504. ic2[k] = U_C2[k] / Zc4 + I4[k];

505. U_A3[k] = Eanuevo[2];

506. ia3[k] = U_A3[k] / Zc5 + I5[k];

507. U_C1[k] = Ecnuevo[0];

508. ic1[k] = U_C1[k] / Zc6 + I6[k];

509.

510. t += deltat;

511. k = k+1;

512. t1[k] = t;

513.

514.

515. //time(&end);

516. auto stop = high_resolution_clock::now();

517. auto duration = duration_cast<microseconds>(stop - start);

518.

519. FILE *fp;

520. fp = fopen("tension.txt", "w");

521.

522. for (int i = 0; i < k-1; i++)

523. fprintf(fp, "%f %f %f %f %f %f \n", U_A2[i], U_B1[i], U_B3[i

], U_C2[i], U_A3[i], U_C1[i]);

524.

525.

526. cout << " Tiempo de ejecucion " << duration.count() << " microse

conds"<< endl;

527.

Page 117: Simulación de transitorios electromagnéticos de sistemas

Anexo D. Código computación paralela metodología CPU-GPU 2 99

528. printf("ultimo valor \n");

529. fclose(fp);

530. return 0;

531.

Page 118: Simulación de transitorios electromagnéticos de sistemas
Page 119: Simulación de transitorios electromagnéticos de sistemas

E. Anexo 5: Código computación paralela metodología GPU-GPU O

1. #include <iostream> 2. #include <cmath> 3. #include <fstream> 4. #include "cuda.h" 5. #include "math.h" 6. #include <cstdio> 7. #include <stdlib.h> 8. #include <chrono> 9. 10. #define M 4 //M es el número de nodos de los subsistemas 11. #define N 6 //N es el número de enlaces entre los subsistemas 12. 13. using namespace std; 14. using namespace std::chrono; 15. 16. __global__ void func1(double *A, double *B, double *C, int Col, int Row)

//Col y Row hacen alusión a la matriz que se esta multiplicando

17. 18. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 19. double tmp = 0; 20. if (ROW < Row) //Multiplicación matriz vector siendo B el vector de

orden Col

21. for (int i = 0; i < Col; i++) 22. tmp += A[ROW * Col + i] * B[i]; 23. 24. 25. 26. C[ROW] = tmp; /*Por la forma como se linealiza la matriz*/ 27. 28. 29. __global__ void func2(double *A, double *B, double *C, double *D, double *

E, double *F, double *G, int Col, int Row)

30. 31. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 32. double tmp = 0; 33. 34. 35. if (ROW < Row) 36. for (int i = 0; i < Col; i++) 37. tmp += A[ROW * Col + i] * B[i] + C[ROW * Col + i] * D[i] + E[R

OW * Col + i] * F[i];

38. 39. 40. 41. G[ROW] = tmp; 42. 43.

Page 120: Simulación de transitorios electromagnéticos de sistemas

102 Simulación de transitorios electromagnéticos mediante programación de GPUs

44. __global__ void func3(double *A, double *B, double *C, double *D, int Row, int Col)

45. 46. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 47. double tmp = 0; 48. if (ROW < Row) 49. for (int i = 0; i < Col; i++) 50. tmp += A[ROW * Col + i] * B[i]; 51. 52. 53. 54. D[ROW] = C[ROW] - tmp; /*Por la forma como se linealiza la matriz*/ 55. //printf("\n C = %f+%f i", C[ROW].x, C[ROW].y);

56. 57. 58. __global__ void func4(int k, double ttao, double *U_A, double *U_B, double

deltat, double Zc, double *i12, double *i21, double *I1, double *I2)

59. int ttao_ind = int(ttao); 60. 61. if (ttao < 0) 62. I1[k] = 0; 63. I2[k] = 0; 64. 65. else 66. 67. I1[k] = -(U_B[ttao_ind] / Zc + i21[ttao_ind]); 68. I2[k] = -(U_A[ttao_ind] / Zc + i12[ttao_ind]); 69. 70. 71. 72. 73. __global__ void func5(int k, double ramp, double *I1, double *I2, double *

I3, double *I4, double *I5, double *I6, double *Ia, double *Ib, double *Ic

)

74. 75. Ia[0] = ramp; 76. Ia[1] = -I1[k]; 77. Ia[2] = -I5[k]; 78. Ia[3] = 0; 79. 80. Ib[0] = -I2[k]; 81. Ib[1] = 0; 82. Ib[2] = -I3[k]; 83. Ib[3] = 0; 84. 85. Ic[0] = -I6[k]; 86. Ic[1] = -I4[k]; 87. Ic[2] = 0; 88. Ic[3] = 0; 89. 90. 91. 92. __global__ void func6(int k, double *U_A2, double *U_B1, double *U_B3, dou

ble *U_C2, double *U_A3, double *U_C1, double *i12, double *i21, double *i

b3, double *ic2, double *ia3, double *ic1, double *Eanuevo, double *Ebnuev

o, double *Ecnuevo, double *I1, double *I2, double *I3, double *I4, double

*I5, double *I6, double Zc1, double Zc3, double Zc5)

93. U_B1[k] = Ebnuevo[0]; 94. i21[k] = U_B1[k] / Zc1 + I2[k]; 95. U_A2[k] = Eanuevo[1];

Page 121: Simulación de transitorios electromagnéticos de sistemas

Anexo E. Código computación paralela metodología GPU-GPU O 103

96. i12[k] = U_A2[k] / Zc1 + I1[k]; 97. U_B3[k] = Ebnuevo[2]; 98. ib3[k] = U_B3[k] / Zc3 + I3[k]; 99. U_C2[k] = Ecnuevo[1]; 100. ic2[k] = U_C2[k] / Zc3 + I4[k];

101. U_A3[k] = Eanuevo[2];

102. ia3[k] = U_A3[k] / Zc5 + I5[k];

103. U_C1[k] = Ecnuevo[0];

104. ic1[k] = U_C1[k] / Zc5 + I6[k];

105.

106.

107. int main(void)

108. double Eanuevo[M], Ebnuevo[M], Ecnuevo[M];

109. double *dEa, *dEb, *dEc, *dInvA, *dInvB, *dInvC, *dIa, *dIb, *dI

c, *dEalpha, *dptrans, *dqtrans, *drtrans, *dIalpha, *dinvZa, *dp, *dq, *d

r, *dIanuevo, *dIbnuevo, *dIcnuevo, *dEanuevo, *dEbnuevo, *dEcnuevo;

110.

111.

112. //Definición matrices inversas

113. double invA[M*M] = 0 ;

114. double invB[M*M] = 0 ;

115. double invC[M*M] = 0 ;

116.

117. ifstream archivo_invA;

118. archivo_invA.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\T

rabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate3g

pu Matlab\\invA.txt");

119.

120. //Comprobación de errores en apertura del archivo

121. if (!archivo_invA.is_open())

122. cout << "Error del archivo1" << endl;

123.

124.

125. for (int i = 0; i < M*M; i++)

126. archivo_invA >> invA[i];

127.

128.

129. archivo_invA.close();

130.

131. ifstream archivo_invB;

132. archivo_invB.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\T

rabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate3g

pu Matlab\\invB.txt");

133.

134. //Comprobación de errores en apertura del archivo

135. if (!archivo_invB.is_open())

136. cout << "Error del archivo2" << endl;

137.

138.

139. for (int i = 0; i < M*M; i++)

140. archivo_invB >> invB[i];

141.

142.

143. archivo_invB.close();

144.

145.

146. ifstream archivo_invC;

147. archivo_invC.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\T

rabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate3g

pu Matlab\\invC.txt");

Page 122: Simulación de transitorios electromagnéticos de sistemas

104 Simulación de transitorios electromagnéticos mediante programación de GPUs

148.

149. //Comprobación de errores en apertura del archivo

150. if (!archivo_invC.is_open())

151. cout << "Error del archivo3" << endl;

152.

153.

154. for (int i = 0; i < M*M; i++)

155. archivo_invC >> invC[i];

156.

157.

158. archivo_invC.close();

159.

160. //Definición parámetros de líneas

161. double delta[3];

162. //línea 1

163. double Zc1 = 200 ;

164. double Zc2 = 200 ;

165. double long1 = 60;

166. double tao1 = long1 / 300000;

167. delta[0] = tao1 / 10;

168. //línea 2

169. double Zc3 = 150 ;

170. double Zc4 = 150 ;

171. double long2 = 40;

172. double tao2 = long2 / 300000;

173. delta[1] = tao2 / 10;

174. //línea 3

175. double Zc5 = 180 ;

176. double Zc6 = 180 ;

177. double long3 = 20;

178. double tao3 = long3 / 300000;

179. delta[2] = tao3 / 10; //Ojo los vectores comienzan desde cero.

180.

181. double deltat = delta[0];

182.

183. for (int i = 1; i < 3; i++)

184. if (delta[i] < deltat)

185. deltat = delta[i];

186.

187.

188.

189.

190. //Inicialización parámetro de tiempo

191. double t = 0;

192. int k = 0; //Inicialización parámetro de posición.

193. size_t kmax = ceil(0.035 / deltat) * sizeof(double);

194.

195.

196.

197. double *I1, *I2, *I3, *I4, *I5, *I6, *t1, *ttao1, *ttao2, *ttao3

;

198. I1 = (double *)malloc(kmax);

199. I2 = (double *)malloc(kmax);

200. I3 = (double *)malloc(kmax);

201. I4 = (double *)malloc(kmax);

202. I5 = (double *)malloc(kmax);

203. I6 = (double *)malloc(kmax);

204. t1 = (double *)malloc(kmax);

205.

206. double U_A2[5260] = 0 ;

207. double U_B1[5260] = 0 ;

Page 123: Simulación de transitorios electromagnéticos de sistemas

Anexo E. Código computación paralela metodología GPU-GPU O 105

208. double U_C2[5260] = 0 ;

209. double U_B3[5260] = 0 ;

210. double U_C1[5260] = 0 ;

211. double U_A3[5260] = 0 ;

212. double i12[5260] = 0 ;

213. double i21[5260] = 0 ;

214. double ic2[5260] = 0 ;

215. double ib3[5260] = 0 ;

216. double ic1[5260] = 0 ;

217. double ia3[5260] = 0 ;

218.

219.

220.

221. I1[0] = 0;

222. I2[0] = 0;

223. I3[0] = 0;

224. I4[0] = 0;

225. I5[0] = 0;

226. I6[0] = 0;

227. t1[0] = 0;

228.

229.

230. //Definición matriz inversa Zalpha

231. double invZa[N*N] = 0 ;

232.

233. ifstream archivo_invZalpha;

234. archivo_invZalpha.open("C:\\Users\\Quartas\\Google Drive\\Maestr

ía\\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\M

ate3gpu Matlab\\invZalpha.txt");

235.

236. //Comprobación de errores en apertura del archivo

237. if (!archivo_invZalpha.is_open())

238. cout << "Error del archivo4" << endl;

239.

240.

241. for (int i = 0; i < N*N; i++)

242. archivo_invZalpha >> invZa[i];

243.

244.

245. archivo_invZalpha.close();

246.

247. //definición matrices de relación traspuestas

248.

249. double ptrans[M*N] = 0;

250. double qtrans[M*N] = 0;

251. double rtrans[M*N] = 0;

252.

253. ifstream archivo_pprima;

254. archivo_pprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate

3gpu Matlab\\pprima.txt");

255.

256. //Comprobación de errores en apertura del archivo

257. if (!archivo_pprima.is_open())

258. cout << "Error del archivo5" << endl;

259.

260.

261. for (int j = 0; j < N*M; j++)

262. archivo_pprima >> ptrans[j];

263.

Page 124: Simulación de transitorios electromagnéticos de sistemas

106 Simulación de transitorios electromagnéticos mediante programación de GPUs

264.

265.

266. archivo_pprima.close();

267.

268.

269. ifstream archivo_qprima;

270. archivo_qprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate

3gpu Matlab\\qprima.txt");

271.

272. //Comprobación de errores en apertura del archivo

273. if (!archivo_qprima.is_open())

274. cout << "Error del archivo6" << endl;

275.

276.

277. for (int j = 0; j < N*M; j++)

278. archivo_qprima >> qtrans[j];

279.

280.

281.

282. archivo_qprima.close();

283.

284. ifstream archivo_rprima;

285. archivo_rprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate

3gpu Matlab\\rprima.txt");

286.

287. //Comprobación de errores en apertura del archivo

288. if (!archivo_rprima.is_open())

289. cout << "Error del archivo7" << endl;

290.

291.

292. for (int j = 0; j < N*M; j++)

293. archivo_rprima >> rtrans[j];

294.

295.

296.

297. archivo_rprima.close();

298.

299. //Definición Matriz p, matriz de orden MxN, asociada a los enlac

es del sistema A.

300. double p[M*N] = 0 ;

301.

302. //Definición Matriz q, matriz de orden MxN, asociada a los enlac

es del sistema B.

303. double q[M*N] = 0 ;

304.

305. //Definición Matriz r, matriz de orden MxN, asociada a los enlac

es del sistema C.

306. double r[M*N] = 0 ;

307.

308. ifstream archivo_p;

309. archivo_p.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate3gpu

Matlab\\p.txt");

310.

311. //Comprobación de errores en apertura del archivo

312. if (!archivo_p.is_open())

313. cout << "Error del archivo8" << endl;

314.

315.

Page 125: Simulación de transitorios electromagnéticos de sistemas

Anexo E. Código computación paralela metodología GPU-GPU O 107

316. for (int j = 0; j < M*N; j++)

317. archivo_p >> p[j];

318.

319.

320.

321. archivo_p.close();

322.

323. ifstream archivo_q;

324. archivo_q.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate3gpu

Matlab\\q.txt");

325.

326. //Comprobación de errores en apertura del archivo

327. if (!archivo_q.is_open())

328. cout << "Error del archivo9" << endl;

329.

330.

331. for (int j = 0; j < M*N; j++)

332. archivo_q >> q[j];

333.

334.

335.

336. archivo_q.close();

337.

338. ifstream archivo_r;

339. archivo_r.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate3gpu\\Mate3gpu

Matlab\\r.txt");

340.

341. //Comprobación de errores en apertura del archivo

342. if (!archivo_r.is_open())

343. cout << "Error del archivo10" << endl;

344.

345.

346. for (int j = 0; j < M*N; j++)

347. archivo_r >> r[j];

348.

349.

350.

351. archivo_r.close();

352.

353. cudaMalloc(&dEa, M * sizeof(double));

354. cudaMalloc(&dEb, M * sizeof(double));

355. cudaMalloc(&dEc, M * sizeof(double));

356. cudaMalloc(&dInvA, M*M * sizeof(double));

357. cudaMalloc(&dInvB, M*M * sizeof(double));

358. cudaMalloc(&dInvC, M*M * sizeof(double));

359. cudaMalloc(&dIa, M * sizeof(double));

360. cudaMalloc(&dIb, M * sizeof(double));

361. cudaMalloc(&dIc, M * sizeof(double));

362.

363.

364. cudaMemcpy(dInvA, invA, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

365. cudaMemcpy(dInvB, invB, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

366. cudaMemcpy(dInvC, invC, (M*M) * sizeof(double), cudaMemcpyHostTo

Device);

367.

368.

Page 126: Simulación de transitorios electromagnéticos de sistemas

108 Simulación de transitorios electromagnéticos mediante programación de GPUs

369. cudaMalloc(&dEalpha, N * sizeof(double));

370. cudaMalloc(&dptrans, (N*M) * sizeof(double));

371. cudaMalloc(&dqtrans, (N*M) * sizeof(double));

372. cudaMalloc(&drtrans, (N*M) * sizeof(double));

373. cudaMemcpy(dptrans, ptrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

374. cudaMemcpy(dqtrans, qtrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

375. cudaMemcpy(drtrans, rtrans, (N*M) * sizeof(double), cudaMemcpyHo

stToDevice);

376.

377.

378. cudaMalloc(&dIalpha, N * sizeof(double));

379. cudaMalloc(&dinvZa, (N*N) * sizeof(double));

380. cudaMemcpy(dinvZa, invZa, (N*N) * sizeof(double), cudaMemcpyHost

ToDevice);

381.

382.

383. cudaMalloc(&dp, (M*N) * sizeof(double));

384. cudaMalloc(&dq, (M*N) * sizeof(double));

385. cudaMalloc(&dr, (M*N) * sizeof(double));

386. cudaMalloc(&dIanuevo, (M) * sizeof(double));

387. cudaMalloc(&dIbnuevo, (M) * sizeof(double));

388. cudaMalloc(&dIcnuevo, (M) * sizeof(double));

389. cudaMemcpy(dp, p, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

390. cudaMemcpy(dq, q, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

391. cudaMemcpy(dr, r, (M*N) * sizeof(double), cudaMemcpyHostToDevice

);

392.

393. cudaMalloc(&dEanuevo, (M) * sizeof(double));

394. cudaMalloc(&dEbnuevo, (M) * sizeof(double));

395. cudaMalloc(&dEcnuevo, (M) * sizeof(double));

396.

397.

398. cudaStream_t stream[3];

399. cudaStreamCreate(&stream[0]);

400. cudaStreamCreate(&stream[1]);

401. cudaStreamCreate(&stream[2]);

402.

403. k = k + 1;

404. t = t + deltat;

405.

406.

407.

408. dim3 blocksPerGrid(1, 1, 1);

409. dim3 threadsPerBlock(M, 1, 1);

410.

411.

412. double *dU_A2, *dU_B1, *dU_C2, *dU_B3, *dU_C1, *dU_A3;

413. cudaMalloc(&dU_A2, kmax);

414. cudaMalloc(&dU_B1, kmax);

415. cudaMalloc(&dU_C2, kmax);

416. cudaMalloc(&dU_B3, kmax);

417. cudaMalloc(&dU_C1, kmax);

418. cudaMalloc(&dU_A3, kmax);

419.

420. cudaMemcpy(dU_A2, U_A2, kmax, cudaMemcpyHostToDevice);

421. cudaMemcpy(dU_B1, U_B1, kmax, cudaMemcpyHostToDevice);

422. cudaMemcpy(dU_C2, U_C2, kmax, cudaMemcpyHostToDevice);

Page 127: Simulación de transitorios electromagnéticos de sistemas

Anexo E. Código computación paralela metodología GPU-GPU O 109

423. cudaMemcpy(dU_B3, U_B3, kmax, cudaMemcpyHostToDevice);

424. cudaMemcpy(dU_C1, U_C1, kmax, cudaMemcpyHostToDevice);

425. cudaMemcpy(dU_A3, U_A3, kmax, cudaMemcpyHostToDevice);

426.

427. double *d_i12, *d_i21, *d_ic2, *d_ib3, *d_ic1, *d_ia3;

428. cudaMalloc(&d_i12, kmax);

429. cudaMalloc(&d_i21, kmax);

430. cudaMalloc(&d_ic2, kmax);

431. cudaMalloc(&d_ib3, kmax);

432. cudaMalloc(&d_ic1, kmax);

433. cudaMalloc(&d_ia3, kmax);

434.

435.

436. cudaMemcpy(d_i12, i12, kmax, cudaMemcpyHostToDevice);

437. cudaMemcpy(d_i21, i21, kmax, cudaMemcpyHostToDevice);

438. cudaMemcpy(d_ic2, ic2, kmax, cudaMemcpyHostToDevice);

439. cudaMemcpy(d_ib3, ib3, kmax, cudaMemcpyHostToDevice);

440. cudaMemcpy(d_ic1, ic1, kmax, cudaMemcpyHostToDevice);

441. cudaMemcpy(d_ia3, ia3, kmax, cudaMemcpyHostToDevice);

442.

443.

444. //I1, I2, I3, I4, I5, I6

445. double *d_I1, *d_I2, *d_I3, *d_I4, *d_I5, *d_I6;

446. cudaMalloc(&d_I1, kmax);

447. cudaMalloc(&d_I2, kmax);

448. cudaMalloc(&d_I3, kmax);

449. cudaMalloc(&d_I4, kmax);

450. cudaMalloc(&d_I5, kmax);

451. cudaMalloc(&d_I6, kmax);

452.

453.

454. printf("Primer valor \n");

455. auto start = high_resolution_clock::now();

456. while (t < 0.035) //35ms es el tiempo máximo de cálculo

457.

458. //indicadores de posición para los valores almacenados

459. int ttao1 = int((t - tao1) / deltat);

460. int ttao2 = int((t - tao2) / deltat);

461. int ttao3 = int((t - tao3) / deltat);

462.

463.

464. threadsPerBlock.x = 1;

465.

466.

467. func4 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

k, ttao1, dU_A2, dU_B1, deltat, Zc1, d_i12, d_i21, d_I1, d_I2);

468. func4 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >

(k, ttao2, dU_B3, dU_C2, deltat, Zc3, d_ib3, d_ic2, d_I3, d_I4);

469. func4 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >

(k, ttao3, dU_A3, dU_C1, deltat, Zc5, d_ia3, d_ic1, d_I5, d_I6);

470.

471. cudaDeviceSynchronize();

472.

473. //Iramp

474. double ramp;

475. if (t < 100 * deltat)

476. ramp = t / (100 * deltat) * 1000;

477. //printf("El valor de la corriente es %f \n", ramp);

478.

479. else

Page 128: Simulación de transitorios electromagnéticos de sistemas

110 Simulación de transitorios electromagnéticos mediante programación de GPUs

480. ramp = 0;

481.

482.

483.

484. func5 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >

(k, ramp, d_I1, d_I2, d_I3, d_I4, d_I5, d_I6, dIa, dIb, dIc);

485. cudaDeviceSynchronize();

486.

487. threadsPerBlock.x = M;

488.

489. //Cálculo de Ea, Eb y Ec en streams diferentes

490.

491. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dInvA, dIa, dEa, M, M);

492. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >(

dInvB, dIb, dEb, M, M);

493. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[2] >> >(

dInvC, dIc, dEc, M, M);

494.

495. cudaDeviceSynchronize();

496.

497. //Cálculo de Ealpha

498.

499. threadsPerBlock.x = N;

500.

501. func2 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dptrans, dEa, dqtrans, dEb, drtrans, dEc, dEalpha, M, N);

502.

503.

504. //Cálculo de Ialpha

505.

506. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dinvZa, dEalpha, dIalpha, N, N);

507. cudaDeviceSynchronize();

508.

509. //Cálculo de corrientes de inyección nuevas

510.

511. threadsPerBlock.x = M;

512.

513.

514. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dp, dIalpha, dIa, dIanuevo, M, N);

515. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >(

dq, dIalpha, dIb, dIbnuevo, M, N);

516. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[2] >> >(

dr, dIalpha, dIc, dIcnuevo, M, N);

517.

518.

519.

520. //Cálculo de tensiones nodales nuevas

521.

522. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

dInvA, dIanuevo, dEanuevo, M, M);

523. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >(

dInvB, dIbnuevo, dEbnuevo, M, M);

524. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[2] >> >(

dInvC, dIcnuevo, dEcnuevo, M, M);

525. cudaDeviceSynchronize;

526.

527. threadsPerBlock.x = 1;

528.

Page 129: Simulación de transitorios electromagnéticos de sistemas

Anexo E. Código computación paralela metodología GPU-GPU O 111

529.

530.

531.

532. func6 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >> >(

k,dU_A2, dU_B1, dU_B3, dU_C2, dU_A3, dU_C1, d_i12, d_i21, d_ib3, d_ic2, d_

ia3, d_ic1, dEanuevo, dEbnuevo, dEcnuevo, d_I1, d_I2, d_I3, d_I4, d_I5, d_

I6, Zc1, Zc3, Zc5);

533. cudaDeviceSynchronize;

534.

535. t = t + deltat;

536. k = k + 1;

537.

538.

539.

540.

541. auto stop = high_resolution_clock::now();

542. auto duration = duration_cast<microseconds>(stop - start);

543. cout << " Tiempo de ejecucion " << duration.count() << " microse

conds" << endl;

544.

545. //dU_A2, dU_B1, dU_B3, dU_C2, dU_A3, dU_C1

546. cudaMemcpy(U_A2, dU_A2, kmax, cudaMemcpyDeviceToHost);

547. cudaMemcpy(U_B1, dU_B1, kmax, cudaMemcpyDeviceToHost);

548. cudaMemcpy(U_B3, dU_B3, kmax, cudaMemcpyDeviceToHost);

549. cudaMemcpy(U_C2, dU_C2, kmax, cudaMemcpyDeviceToHost);

550. cudaMemcpy(U_A3, dU_A3, kmax, cudaMemcpyDeviceToHost);

551. cudaMemcpy(U_C1, dU_C1, kmax, cudaMemcpyDeviceToHost);

552.

553. FILE *fp;

554. fp = fopen("tension.txt", "w");

555.

556. for (int i = 0; i < k-1; i++)

557. fprintf(fp, "%f %f %f %f %f %f \n", U_A2[i], U_B1[i], U_B3[i

], U_C2[i], U_A3[i], U_C1[i]);

558.

559.

560. fclose(fp);

561.

562. printf("ultimo valor \n");

563. return 0;

564.

Page 130: Simulación de transitorios electromagnéticos de sistemas
Page 131: Simulación de transitorios electromagnéticos de sistemas

F. Anexo 6: Código CUDA para la solución de transitorios de sistema eléctrico aleatorio en la GPU

1. //Se definen las librerias necesarias 2. #include <iostream> 3. #include <cmath> 4. #include <fstream> 5. #include "cuda.h" 6. #include "math.h" 7. #include <cstdio> 8. #include <stdlib.h> 9. #include <chrono> 10. 11. double P[2000][4 * 2000 * 2] = 0 ; //Para crear inicialmente el vector

P, se prevee que máximo se generaran 2000 sistemas, 2000 enlaces y cada si

stema tiene un valor fijo de nodos igual a 4

12. double Pprima[2000][2000 * 2 * 4] = 0 ; //Para crear inicialmente el vector P', se prevee que máximo se generaran 2000 sistemas, 2000 enlaces y c

ada sistema tiene un valor fijo de nodos igual a 4

13. double Pabs[2000][4 * 2000 * 2] = 0 ; //Para crear inicialmente el vector P, se prevee que máximo se generaran 2000 sistemas, 2000 enlaces y cada

sistema tiene un valor fijo de nodos igual a 4

14. double invZalpha[2000 * 2 * 2000 * 2] = 0 ; //Se prevé un sistema de max 2000 enlaces

15. double nod_UA[2000] = 0 ; //Máximo 2000 enlaces 16. double nod_UB[2000] = 0 ; //Máximo 2000 enlaces 17. double sist_UA[2000] = 0 ; //Máximo 2000 enlaces 18. double sist_UB[2000] = 0 ; //Máximo 2000 enlaces 19. 20. __global__ void func1(int k, double ttao, double Zc, double *U_A, double *

U_B, double *i12, double *i21, double *I1, double *I2) //Para cálculo de

corrientes de línea

21. 22. 23.

//int k1 = int(k);

24. int ttao1 = int(ttao); 25. 26. if (ttao < 0) 27. I1[k] = 0; 28. I2[k] = 0; 29. 30. else 31. I1[k] = -(U_B[ttao1] / Zc + i21[ttao1]); 32. I2[k] = -(U_A[ttao1] / Zc + i12[ttao1]); 33. 34.

Page 132: Simulación de transitorios electromagnéticos de sistemas

114 Simulación de transitorios electromagnéticos mediante programación de GPUs

35. 36. 37. __global__ void func7(int i, int j, int h, int k, double *I1, double *I2,

double *Ilineas)

38. 39. 40. 41. 42. if (j % 2 == 0) 43. Ilineas[h] = -I1[k]; 44. 45. else if (j % 2 != 0) 46. Ilineas[h] = -I2[k]; 47. 48. 49. 50. 51. 52. __global__ void func3(double *A, double *B, double *C, int Col, int Row)

//Col y Row hacen alusión a la matriz que esta multiplicando

53. 54. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 55. double tmp = 0; 56. if (ROW < Row) //Multiplicación matriz vector siendo B el vector de

orden Col

57. for (int i = 0; i < Col; i++) 58. tmp += A[ROW * Col + i] * B[i]; 59. 60. 61. 62. C[ROW] = tmp; /*Por la forma como se linealiza la matriz*/ 63. 64. 65. __global__ void func3_1(int rampa, double *I_iny, double Iramp) 66. I_iny[rampa] = Iramp; 67. 68. 69. 70. __global__ void func4_1(double *A, double *B, int Row) // Row hace alusió

n a la dimensión de los vectores que se estan sumando

71. 72. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 73. if (ROW < Row) //Multiplicación matriz vector siendo B el vector de

orden Col

74. B[ROW] = A[ROW]; 75. 76. 77. 78. 79. __global__ void func4_2(double *A, double *B, int Row) //Row hace alusión

a la dimensión de los vectores que se estan sumando

80. 81. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 82. 83. if (ROW < Row) //Multiplicación matriz vector siendo B el vector de

orden Col

84. 85. B[ROW] = B[ROW] + A[ROW]; 86. 87. 88.

Page 133: Simulación de transitorios electromagnéticos de sistemas

Anexo F. Código CUDA para la solución de transitorios de sistema eléctrico

aleatorio en la GPU

115

89. 90. __global__ void func5(double *A, double *B, double *C, double *D, int Row,

int Col)

91. 92. int ROW = blockIdx.x*blockDim.x + threadIdx.x; 93. double tmp = 0; 94. if (ROW < Row) 95. for (int i = 0; i < Col; i++) 96. tmp += A[ROW * Col + i] * B[i]; 97. 98. 99. 100. D[ROW] = C[ROW] - tmp; /*Por la forma como se linealiza la matri

z*/

101. //printf("\n C = %f+%f i", C[ROW].x, C[RO

W].y);

102.

103.

104. __global__ void func6_1(double *U_A, double *U_B, double *i12, doubl

e *i21, double *Eanuevo, double *Ebnuevo, double *I1, double *I2, int Zc,

int k, double nod_UA, double nod_UB)

105.

106. int ind_A = int(nod_UA);

107. int ind_B = int(nod_UB);

108.

109.

110.

111. U_A[k] = Eanuevo[ind_A];

112. U_B[k] = Ebnuevo[ind_B];

113. i12[k] = U_A[k] / Zc + I1[k];

114. i21[k] = U_B[k] / Zc + I2[k];

115.

116.

117.

118.

119. int main(void)

120.

121. double M, L, N, Zc, tao;

122.

123. using namespace std;

124. using namespace std::chrono;

125.

126. dim3 blocksPerGrid(1, 1, 1);

127. dim3 threadsPerBlock(1, 1, 1);

128.

129. cudaStream_t stream[2000]; //Máximo 2000 sistemas

130.

131. for (int i = 0; i < 2000; i++) //se crean 2000 streams

132. cudaStreamCreate(&stream[i]);

133.

134.

135.

136. //Lectura de archivos con parámetros

137.

138. ifstream archivo_param;

139. archivo_param.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\

Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio2

\\Mate_aleatorio2_MATLAB\\param.txt");

140.

Page 134: Simulación de transitorios electromagnéticos de sistemas

116 Simulación de transitorios electromagnéticos mediante programación de GPUs

141. //Comprobación de errores en apertura del archivo

142. if (!archivo_param.is_open())

143. cout << "Error del archivo1" << endl;

144.

145. archivo_param >> M >> L >> N >> Zc >> tao;

146. cout << M << endl; //M es número de sistemas

147. cout << L << endl; //L es número de enlaces

148. cout << N << endl; //N es el número de nodos de los subsistemas

, N es igual en ambos subsistemas A y B

149. cout << Zc << endl; //Zc es la impedancia caracteristica de los

enlaces, todos los enlaces igual Zc

150. cout << tao << endl; // tao es el tiempo de viaje en las líneas,

igual en todos los enlaces

151.

152.

153. archivo_param.close();

154.

155. //Lectura de archivos con matrices inversas

156. double invA[16] = 0 ; //se limita el tamaño de los subsistem

as a 4 nodos.

157. double invB[16] = 0 ;

158. ifstream archivo_invA;

159. archivo_invA.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\T

rabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio2\

\Mate_aleatorio2_MATLAB\\invA.txt");

160.

161. //Comprobación de errores en apertura del archivo

162. if (!archivo_invA.is_open())

163. cout << "Error del archivo2" << endl;

164.

165.

166. for (int i = 0; i < N*N; i++)

167. archivo_invA >> invA[i];

168.

169.

170. archivo_invA.close();

171.

172. ifstream archivo_invB;

173. archivo_invB.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\T

rabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio2\

\Mate_aleatorio2_MATLAB\\invB.txt");

174.

175. //Comprobación de errores en apertura del archivo

176. if (!archivo_invB.is_open())

177. cout << "Error del archivo3" << endl;

178.

179.

180. for (int i = 0; i < N*N; i++)

181. archivo_invB >> invB[i];

182.

183.

184. archivo_invB.close();

185.

186. ifstream archivo_P;

187. archivo_P.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\Trab

ajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio2\\Ma

te_aleatorio2_MATLAB\\P.txt");

188.

189. //Comprobación de errores en apertura del archivo

190. if (!archivo_P.is_open())

191. cout << "Error del archivo4" << endl;

Page 135: Simulación de transitorios electromagnéticos de sistemas

Anexo F. Código CUDA para la solución de transitorios de sistema eléctrico

aleatorio en la GPU

117

192.

193.

194. for (int i = 0; i < M; i++)

195. for (int j = 0; j < N*L * 2; j++)

196. archivo_P >> P[i][j];

197.

198.

199.

200. archivo_P.close();

201.

202.

203.

204. ifstream archivo_Pprima;

205. archivo_Pprima.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio

2\\Mate_aleatorio2_MATLAB\\Pprima.txt");

206.

207. //Comprobación de errores en apertura del archivo

208. if (!archivo_Pprima.is_open())

209. cout << "Error del archivo5" << endl;

210.

211.

212.

213. for (int i = 0; i < M; i++)

214. for (int j = 0; j < L * 2 * N; j++)

215. archivo_Pprima >> Pprima[i][j];

216.

217.

218.

219.

220. archivo_Pprima.close();

221.

222.

223.

224. ifstream archivo_Pabs;

225. archivo_Pabs.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\T

rabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio2\

\Mate_aleatorio2_MATLAB\\Pabs.txt");

226.

227. //Comprobación de errores en apertura del archivo

228. if (!archivo_Pabs.is_open())

229. cout << "Error del archivo6" << endl;

230.

231.

232. for (int i = 0; i < M; i++)

233. for (int j = 0; j < N*L * 2; j++)

234. archivo_Pabs >> Pabs[i][j];

235.

236.

237.

238. archivo_Pabs.close();

239.

240.

241. ifstream archivo_invZalpha;

242. archivo_invZalpha.open("C:\\Users\\Quartas\\Google Drive\\Maestr

ía\\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleato

rio2\\Mate_aleatorio2_MATLAB\\invZalpha.txt");

243.

244. //Comprobación de errores en apertura del archivo

Page 136: Simulación de transitorios electromagnéticos de sistemas

118 Simulación de transitorios electromagnéticos mediante programación de GPUs

245. if (!archivo_invZalpha.is_open())

246. cout << "Error del archivo7" << endl;

247.

248.

249. for (int i = 0; i < L * 2 * L * 2; i++)

250. archivo_invZalpha >> invZalpha[i];

251.

252.

253. archivo_invZalpha.close();

254.

255.

256. ifstream archivo_nod_UA;

257. archivo_nod_UA.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio

2\\Mate_aleatorio2_MATLAB\\nod_UA.txt");

258.

259. //Comprobación de errores en apertura del archivo

260. if (!archivo_nod_UA.is_open())

261. cout << "Error del archivo8" << endl;

262.

263.

264. for (int i = 0; i < L ; i++)

265. archivo_nod_UA >>nod_UA[i];

266.

267.

268. archivo_nod_UA.close();

269.

270. ifstream archivo_nod_UB;

271. archivo_nod_UB.open("C:\\Users\\Quartas\\Google Drive\\Maestría\

\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio

2\\Mate_aleatorio2_MATLAB\\nod_UB.txt");

272.

273. //Comprobación de errores en apertura del archivo

274. if (!archivo_nod_UB.is_open())

275. cout << "Error del archivo9" << endl;

276.

277.

278. for (int i = 0; i < L; i++)

279. archivo_nod_UB >> nod_UB[i];

280.

281.

282. archivo_nod_UB.close();

283.

284.

285. ifstream archivo_sist_UA;

286. archivo_sist_UA.open("C:\\Users\\Quartas\\Google Drive\\Maestría

\\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatori

o2\\Mate_aleatorio2_MATLAB\\sist_UA.txt");

287.

288. //Comprobación de errores en apertura del archivo

289. if (!archivo_sist_UA.is_open())

290. cout << "Error del archivo10" << endl;

291.

292.

293. for (int i = 0; i < L; i++)

294. archivo_sist_UA >> sist_UA[i];

295.

296.

297. archivo_sist_UA.close();

298.

299. ifstream archivo_sist_UB;

Page 137: Simulación de transitorios electromagnéticos de sistemas

Anexo F. Código CUDA para la solución de transitorios de sistema eléctrico

aleatorio en la GPU

119

300. archivo_sist_UB.open("C:\\Users\\Quartas\\Google Drive\\Maestría

\\Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatori

o2\\Mate_aleatorio2_MATLAB\\sist_UB.txt");

301.

302. //Comprobación de errores en apertura del archivo

303. if (!archivo_sist_UB.is_open())

304. cout << "Error del archivo11" << endl;

305.

306.

307. for (int i = 0; i < L; i++)

308. archivo_sist_UB >> sist_UB[i];

309.

310.

311. archivo_sist_UB.close();

312.

313. double dispo[4] = 0 ;

314.

315. ifstream archivo_dispo;

316. archivo_dispo.open("C:\\Users\\Quartas\\Google Drive\\Maestría\\

Trabajo con Javier Herrera\\Tareas\\16. Códigos a validar\\Mate_aleatorio2

\\Mate_aleatorio2_MATLAB\\dispo.txt");

317.

318. //Comprobación de errores en apertura del archivo

319. if (!archivo_dispo.is_open())

320. cout << "Error del archivo12" << endl;

321.

322.

323. int rampa;

324. rampa = 100; //valor por fuera de los nodos, solo para verificar

si hay disponibilidad.

325.

326. for (int i = 0; i < N; i++) //Tomar solo primer sistema

327. archivo_dispo >> dispo[i];

328. if (dispo[i] == 0)

329. rampa = i;

330.

331.

332.

333. if (rampa == 100)

334. cout << "no hay nodos disponibles sistema 1 para Iramp" << e

ndl;

335.

336.

337. else if (rampa != 100)

338. cout << "Iramp estará conectada a nodo: " << rampa+1 << endl

;

339.

340.

341.

342. //Tiempo máximo de ejecución 35 ms

343. double deltat = tao / 10; //paso de tiempo definido como la deci

ma parte de tao

344. //cout << deltat << endl;

345.

346. double kmax = (0.0350) / deltat;

347. //cout << "Pasos son: "<<kmax << endl;

348.

349. double *d_I1[2000], *d_I2[2000]; //sistema de máximo 2000 enlac

es

Page 138: Simulación de transitorios electromagnéticos de sistemas

120 Simulación de transitorios electromagnéticos mediante programación de GPUs

350.

351. for (int i = 0; i < L; i++)

352.

353. cudaMalloc(&d_I1[i], sizeof(double)*kmax);

354. cudaMalloc(&d_I2[i], sizeof(double)*kmax);

355.

356.

357.

358. //Tensiones asociadas a los extremos de línea

359.

360. double *U_A[2000], *U_B[2000]; //Máximo 2000 sistemas, 2000 enla

ces

361. for (int i = 0; i < L; i++)

362. U_A[i] = (double *)malloc(sizeof(double)*kmax);

363. U_B[i] = (double *)malloc(sizeof(double)*kmax);

364.

365.

366. for (int i = 0; i < L; i++)

367. for (int j = 0; j < kmax; j++)

368. U_A[i][j] = 0;

369. U_B[i][j] = 0;

370.

371.

372.

373.

374. double *dU_A[2000], *dU_B[2000]; //Máximo 2000 sistemas y 2000 e

nlaces

375. for (int i = 0; i < L; i++)

376. cudaMalloc(&dU_A[i], sizeof(double)*kmax);

377. cudaMalloc(&dU_B[i], sizeof(double)*kmax);

378.

379.

380. for (int i = 0; i < L; i++)

381. cudaMemcpy(dU_A[i], U_A[i], sizeof(double)*kmax, cudaMemcpyH

ostToDevice);

382. cudaMemcpy(dU_B[i], U_B[i], sizeof(double)*kmax, cudaMemcpyH

ostToDevice);

383.

384.

385. //Parámetro tiempo

386. double t = deltat;

387.

388. double ttao = (t - tao) / deltat;

389.

390. int k = 1;

391.

392. //Parámetro tao ya fue leído del archivo

393.

394. //Parámetro Zc ya fue leído del archivo

395.

396. //Corrientes asociadas a las líneas i12 e i21.

397.

398. double *i12[2000], *i21[2000]; //Máximo 2000 sistemas y 2000 enl

aces

399. for (int i = 0; i < L; i++)

400. i12[i] = (double *)malloc(sizeof(double)*kmax);

401. i21[i] = (double *)malloc(sizeof(double)*kmax);

402.

403.

404. for (int i = 0; i < L; i++)

405. for (int j = 0; j < kmax; j++)

Page 139: Simulación de transitorios electromagnéticos de sistemas

Anexo F. Código CUDA para la solución de transitorios de sistema eléctrico

aleatorio en la GPU

121

406. i12[i][j] = 0;

407. i21[i][j] = 0;

408.

409.

410.

411.

412. double *d_i12[2000], *d_i21[2000]; //Máximo 2000 sistemas y 2000

enlaces

413. for (int i = 0; i < L; i++)

414. cudaMalloc(&d_i12[i], sizeof(double)*kmax);

415. cudaMalloc(&d_i21[i], sizeof(double)*kmax);

416.

417.

418. for (int i = 0; i < L; i++)

419. cudaMemcpy(d_i12[i], i12[i], sizeof(double)*kmax, cudaMemcpy

HostToDevice);

420. cudaMemcpy(d_i21[i], i21[i], sizeof(double)*kmax, cudaMemcpy

HostToDevice);

421.

422.

423. //Corrientes de inyección

424.

425. double *dI_iny[2000]; //máximo 2000 subsistemas

426.

427. for (int i = 0; i < M; i++)

428.

429. cudaMalloc(&dI_iny[i], sizeof(double)*N);

430.

431.

432. double Iramp;

433. //Pasar las matrices inversas InvA e InvB a la GPU

434. double *d_invA, *d_invB;

435. cudaMalloc(&d_invA, sizeof(double)*N*N);

436. cudaMalloc(&d_invB, sizeof(double)*N*N);

437. cudaMemcpy(d_invA, invA, sizeof(double)*N*N, cudaMemcpyHostToDev

ice);

438. cudaMemcpy(d_invB, invB, sizeof(double)*N*N, cudaMemcpyHostToDev

ice);

439.

440. // dEa, una única variables dEa[sistema][nodo]

441. double *d_Ea[2000]; //máximo 2000 sistemas

442.

443. for (int i = 0; i < M; i++)

444.

445. cudaMalloc(&d_Ea[i], sizeof(double)*N);

446.

447.

448. //dEalpha_temp es cada una de las partes de Ealpha asociada a ca

da sistema, las cuales al final se sumarán

449. double *dEalpha_temp[2000]; //Máximo 2000 sistemas

450.

451. for (int i = 0; i < M; i++)

452.

453. cudaMalloc(&dEalpha_temp[i], sizeof(double)*L * 2);

454.

455.

456. //Transfiero Pprima a la GPU

457.

458. double *d_Pprima[2000]; //máximo 2000 sistemas

Page 140: Simulación de transitorios electromagnéticos de sistemas

122 Simulación de transitorios electromagnéticos mediante programación de GPUs

459.

460. for (int i = 0; i < M; i++)

461.

462. cudaMalloc(&d_Pprima[i], sizeof(double)*L * 2 * N);

463.

464.

465. for (int i = 0; i < M; i++)

466. cudaMemcpy(d_Pprima[i], Pprima[i], sizeof(double)*L * 2 * N,

cudaMemcpyHostToDevice);

467.

468.

469.

470. //Ealpha total

471.

472. double *dEalpha;

473. cudaMalloc(&dEalpha, L * 2 * sizeof(double));

474.

475. //Ialpha

476.

477. double *dIalpha;

478. cudaMalloc(&dIalpha, L * 2 * sizeof(double));

479.

480. //Transferir invZalpha a GPU

481.

482. double *d_invZalpha;

483. cudaMalloc(&d_invZalpha, sizeof(double)*L * 2 * L * 2);

484. cudaMemcpy(d_invZalpha, invZalpha, sizeof(double)*L * 2 * L * 2,

cudaMemcpyHostToDevice);

485.

486. //Ianuevo

487.

488. double *d_Ianuevo[2000]; //máximo 2000 subsistemas

489.

490. for (int i = 0; i < M; i++)

491.

492. cudaMalloc(&d_Ianuevo[i], sizeof(double)*N);

493.

494.

495. //Transferir P a GPU

496.

497. double *d_P[2000]; //máximo 2000 sistemas

498.

499. for (int i = 0; i < M; i++)

500.

501. cudaMalloc(&d_P[i], sizeof(double)* N*L * 2);

502.

503.

504. for (int i = 0; i < M; i++)

505. cudaMemcpy(d_P[i], P[i], sizeof(double) *N*L * 2, cudaMemcpy

HostToDevice);

506.

507.

508.

509. //Transferir Pabs a GPU

510.

511. double *d_Pabs[2000]; //máximo 2000 sistemas

512.

513. for (int i = 0; i < M; i++)

514.

515. cudaMalloc(&d_Pabs[i], sizeof(double)* N*L * 2);

516.

Page 141: Simulación de transitorios electromagnéticos de sistemas

Anexo F. Código CUDA para la solución de transitorios de sistema eléctrico

aleatorio en la GPU

123

517.

518. for (int i = 0; i < M; i++)

519. cudaMemcpy(d_Pabs[i], Pabs[i], sizeof(double) *N*L * 2, cuda

MemcpyHostToDevice);

520.

521.

522.

523. //Eanuevo

524.

525. double *d_Eanuevo[2000]; //máximo 2000 subsistemas

526.

527. for (int i = 0; i < M; i++)

528.

529. cudaMalloc(&d_Eanuevo[i], sizeof(double)*N);

530.

531.

532. //Sist U_A, sist U_B, nod U_A y nod U_B

533.

534. double *dsist_UA, *dsist_UB, *dnod_UA, *dnod_UB;

535. cudaMalloc(&dsist_UA, L* sizeof(double));

536. cudaMalloc(&dsist_UB, L * sizeof(double));

537. cudaMalloc(&dnod_UA, L * sizeof(double));

538. cudaMalloc(&dnod_UB, L * sizeof(double));

539.

540. cudaMemcpy(dsist_UA, sist_UA, sizeof(double) *L, cudaMemcpyHostT

oDevice);

541. cudaMemcpy(dsist_UB, sist_UB, sizeof(double) *L, cudaMemcpyHostT

oDevice);

542. cudaMemcpy(dnod_UA, nod_UA, sizeof(double) *L, cudaMemcpyHostToD

evice);

543. cudaMemcpy(dnod_UB, nod_UB, sizeof(double) *L, cudaMemcpyHostToD

evice);

544.

545. //Vector para todas las I de las líneas, usado para el cálculo d

e las corrientes de inyección

546. double *d_Ilineas; //máximo 2000 enlaces

547. cudaMalloc(&d_Ilineas, sizeof(double)*L*2);

548.

549. int sist_A = 0;

550. int sist_B = 0;

551.

552.

553.

554. printf("Primer valor \n");

555. auto start = high_resolution_clock::now();

556. while (t < 0.035) //35ms es el tiempo máximo de cálculo

557.

558. if (t <= 100 * deltat)

559. Iramp = t / (100 * deltat) * 10000;

560.

561. else

562. Iramp = 0;

563.

564.

565. threadsPerBlock.x = 1;

566.

567. for (int i = 0; i < L; i++)

Page 142: Simulación de transitorios electromagnéticos de sistemas

124 Simulación de transitorios electromagnéticos mediante programación de GPUs

568. func1 << <blocksPerGrid, threadsPerBlock, 0, stream[i] >

> > (k, ttao, Zc, dU_A[i], dU_B[i], d_i12[i], d_i21[i], d_I1[i], d_I2[i]);

569.

570. cudaDeviceSynchronize();

571.

572.

573. int h = 0;

574. for (int i = 0; i < L ; i++)

575. for (int j = 0; j < 2; j++)

576. //cout << "paso " << j<< endl;

577. func7 << <blocksPerGrid, threadsPerBlock, 0, stream[

i] >> > (i, j, h, k, d_I1[i], d_I2[i], d_Ilineas);

578. h = h + 1;

579.

580.

581.

582.

583.

584. cudaDeviceSynchronize();

585.

586.

587. //Cálculo de las corrientes de inyección

588.

589. threadsPerBlock.x = N;

590.

591. for (int i = 0; i < M; i++)

592. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[i] >

> > (d_Pabs[i], d_Ilineas, dI_iny[i], L*2, N);

593.

594.

595. func3_1 << <blocksPerGrid, threadsPerBlock, 0, stream[0] >>

> (rampa, dI_iny[0], Iramp);

596.

597. cudaDeviceSynchronize();

598.

599. //Cálculo de Ea

600.

601. threadsPerBlock.x = N; //invA es una matriz 4x4

602.

603. for (int i = 0; i < M; i++)

604. if (i == 0)

605. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[

i] >> > (d_invA, dI_iny[i], d_Ea[i], N, N);

606.

607. if (i != 0)

608. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[

i] >> > (d_invB, dI_iny[i], d_Ea[i], N, N);

609.

610.

611.

612.

613. cudaDeviceSynchronize();

614.

615. //Cálculo de Ealpha

616.

617. threadsPerBlock.x = L * 2; //Pprima es una matriz de orden L

x2

618.

619. for (int i = 0; i < M; i++)

Page 143: Simulación de transitorios electromagnéticos de sistemas

Anexo F. Código CUDA para la solución de transitorios de sistema eléctrico

aleatorio en la GPU

125

620. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[i] >

> > (d_Pprima[i], d_Ea[i], dEalpha_temp[i], N, L * 2);

621.

622.

623. cudaDeviceSynchronize();

624.

625.

626. for (int i = 0; i < M; i++)

627. if (i == 0)

628. func4_1 << <blocksPerGrid, threadsPerBlock, 0, strea

m[0] >> > (dEalpha_temp[i], dEalpha, L * 2);

629.

630. if (i != 0)

631. func4_2 << <blocksPerGrid, threadsPerBlock, 0, strea

m[0] >> > (dEalpha_temp[i], dEalpha, L * 2);

632.

633.

634.

635.

636. cudaDeviceSynchronize();

637.

638. //Cálculo de Ialpha

639.

640. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[1] >> >

(d_invZalpha, dEalpha, dIalpha, L * 2, L * 2);

641.

642. cudaDeviceSynchronize();

643.

644. //Cálculo de Ia nuevo

645.

646. threadsPerBlock.x = N; //P es de orden N* (Lx2)

647.

648. for (int i = 0; i < M; i++)

649. func5 << <blocksPerGrid, threadsPerBlock, 0, stream[i] >

> > (d_P[i], dIalpha, dI_iny[i], d_Ianuevo[i], N, L * 2);

650.

651.

652. cudaDeviceSynchronize();

653.

654. //Cálculo de Eanuevo

655.

656. for (int i = 0; i < M; i++)

657. if (i == 0)

658. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[

i] >> > (d_invA, d_Ianuevo[i], d_Eanuevo[i], N, N);

659.

660. if (i != 0)

661. func3 << <blocksPerGrid, threadsPerBlock, 0, stream[

i] >> > (d_invB, d_Ianuevo[i], d_Eanuevo[i], N, N);

662.

663.

664.

665.

666. cudaDeviceSynchronize();

667.

668. threadsPerBlock.x = 1;

669. for (int i = 0; i < L; i++)

670. sist_A = int(sist_UA[i]);

671. sist_B = int(sist_UB[i]);

Page 144: Simulación de transitorios electromagnéticos de sistemas

126 Simulación de transitorios electromagnéticos mediante programación de GPUs

672. //cout << "sist A " << sist_A<<endl;

673. func6_1<< <blocksPerGrid, threadsPerBlock, 0, stream[i]

>> > (dU_A[i], dU_B[i],d_i12[i], d_i21[i], d_Eanuevo[sist_A], d_Eanuevo[si

st_B], d_I1[i], d_I2[i], Zc, k, nod_UA[i], nod_UB[i]);

674.

675.

676.

677. cudaDeviceSynchronize();

678.

679.

680.

681. t = t + deltat;

682. k = k + 1;

683. ttao = (t - tao) / deltat;

684.

685.

686. auto stop = high_resolution_clock::now();

687. auto duration = duration_cast<microseconds>(stop - start);

688. cout << " con " << M << " sistemas" << endl;

689. cout << " con " << L << " enlaces" << endl;

690. cout << " Tiempo de ejecucion " << duration.count() << " microse

conds" << endl;

691.

692.

693. for (int i = 0; i < L; i++)

694. cudaMemcpy(U_A[i], dU_A[i], sizeof(double)*kmax, cudaMemcpyD

eviceToHost);

695. cudaMemcpy(U_B[i], dU_B[i], sizeof(double)*kmax, cudaMemcpyD

eviceToHost);

696.

697.

698. //Se crean un solo archivo, una columna para U_A y otra para U_B

699.

700. FILE *fp;

701. fp = fopen("CUDA_Ulinea.txt", "w");

702.

703. for (int i = 0; i < L; i++)

704. for (int j = 0; j < kmax; j++)

705. fprintf(fp, "%f %f\n", U_A[i][j], U_B[i][j]);

706.

707.

708.

709.

710.

711. fclose(fp);

712.

713.

714. printf("último valor \n");

715. cudaDeviceReset();

716. return 0;

717.

Page 145: Simulación de transitorios electromagnéticos de sistemas

G. Anexo 7: Código en MATLAB para la solución de transitorios de sistema eléctrico aleatorio en la CPU

1. %Antes de ejecutar este programa se debe haber ejecutado el de generación

2. clc 3. 4. k=1; %Contador de posiciones para almacenar los datos 5. t=0; %Se inicia el tiempo 6. 7. U_A=zeros(L,kmax); 8. U_B=zeros(L,kmax); 9. i12=zeros(L,kmax); 10. i21=zeros(L,kmax); 11. 12. tmax=35e-3; %tiempo máximo de simulación 13. t=t+deltat; 14. k=k+1; 15. 16. rampa=100; 17. for i=1:N 18. if dispo(1,i)==0 19. rampa=i; 20. end 21. end 22. if rampa==100 23. disp("no hay nodos disponibles sistema 1 para Iramp") 24. elseif rampa~=100 25. fprintf("Iram estará conectada a nodo %d\n",rampa); 26. end 27. 28. tic 29. while (t<=tmax) 30. ttao=((t-tao)/deltat+1); %Indicador de posición para cada línea, t-

tao

31. 32. 33. %Fuente rampa 34. if t< 100*deltat 35. ramp(k)=t/(100*deltat)*10000; 36. else 37. ramp(k)=0; 38. end 39. %cálculo corrientes de línea 40.

Page 146: Simulación de transitorios electromagnéticos de sistemas

128 Simulación de transitorios electromagnéticos mediante programación de GPUs

41. 42. for i=1:L 43. if ttao<1 44. I1(i,k)=0; 45. I2(i,k)=0; 46. elseif ttao>=1 47. I1(i,k)=-(U_B(i,round(ttao))/Zc+i21(i,round(ttao))); 48. I2(i,k)=-(U_A(i,round(ttao))/Zc+i12(i,round(ttao))); 49. end 50. end 51. 52. %Armo vector Ilineas para corrientes de inyección 53. h=1; 54. for i=1:L 55. for j=1:2 56. if j==1 57. Ilineas(h)=-I1(i,k); 58. elseif j==2 59. Ilineas(h)=-I2(i,k); 60. end 61. h=h+1; 62. end 63. end 64. 65. for i=1:M 66. I_iny(:,i)=Pabs(:,:,i)*(Ilineas'); 67. end 68. 69. I_iny(rampa,1)=ramp(k); 70. 71. %calculo de Ea 72. for i=1:M 73. Ea(:,i)=invA*I_iny(:,i); 74. end 75. 76. %calculo de Ealpha 77. 78. Ealpha= zeros(L*2,1); 79. 80. for i=1:M 81. Ealpha=Pprima(:,:,i)*Ea(:,i)+Ealpha; 82. end 83. Ialpha= invZalpha*Ealpha; 84. 85. for i=1:M 86. if i==1 87. Eanuevo(:,i)=invA*(I_iny(:,i)-P(:,:,i)*Ialpha); 88. else 89. Eanuevo(:,i)=invB*(I_iny(:,i)-P(:,:,i)*Ialpha); 90. end 91. end 92. 93. %Actualización de parámetros 94. 95. for i=1:L 96. 97. U_A(i,k)=Eanuevo(nod_UA(i)+1,sist_UA(i)+1); 98. U_B(i,k)=Eanuevo(nod_UB(i)+1,sist_UB(i)+1); 99. i12(i,k)= U_A(i,k)/Zc+I1(i,k); 100. i21(i,k)= U_B(i,k)/Zc+I2(i,k);

101.

Page 147: Simulación de transitorios electromagnéticos de sistemas

Anexo G. Código MATLAB para la solución de transitorios de sistema

eléctrico aleatorio en la CPU

129

102. end

103.

104.

105. t=t+deltat;

106. k=k+1;

107. end

108. toc

109. M

110. L

111.

112. U_A(:,kmax+1)=[];

113. U_B(:,kmax+1)=[];

114.

115. figure(1)

116. hold on

117. plot(t2,U_A(1,:),'r');

118. figure(2)

119. hold on

120. plot(t2,U_B(1,:),'r');

Page 148: Simulación de transitorios electromagnéticos de sistemas
Page 149: Simulación de transitorios electromagnéticos de sistemas

H. Anexo 8: Código en MATLAB para la generación de sistemas eléctricos aleatorios

1. %Código para la generación aleatoria de sistemas de topología variada. 2. %Se emplean dos tipos de sistemas, A y B 3. clear all 4. close all 5. clc 6. tic 7. %Sistema A Conformado por resistencias 8. Ra12=20; 9. Ra23=10; 10. Ra34=2.5; 11. Ra14=5; 12. Ra4=2; 13. %Se calculan admitancias del sistema A 14. Ga12=1/Ra12; 15. Ga23=1/Ra23; 16. Ga34=1/Ra34; 17. Ga14=1/Ra14; 18. Ga4=1/Ra4; 19. 20. A=[Ga12+Ga14 -Ga12 0 -Ga14;-Ga12 Ga12+Ga23 -Ga23 0;0 -Ga23 Ga23+Ga34 -Ga34;-Ga14 0 -

Ga34 Ga14+Ga34+Ga4]; %Matriz de admitancia sistema A 21. invA= inv(A); 22. %Sistema B Conformado por resistencias 23. Rb12=7; 24. Rb23=5; 25. Rb34=2; 26. Rb14=10; 27. Rb4=8; 28. %Se calculan admitancias del sistema B 29. Gb12=1/Rb12; 30. Gb23=1/Rb23; 31. Gb34=1/Rb34; 32. Gb14=1/Rb14; 33. Gb4=1/Rb4; 34. 35. B=[Gb12+Gb14 -Gb12 0 -Gb14;-Gb12 Gb12+Gb23 -Gb23 0;0 -Gb23 Gb23+Gb34 -Gb34;-Gb14 0 -

Gb34 Gb14+Gb34+Gb4];%Matriz de admitancia sistema B 36. invB= inv(B); 37. %Solo se considera un tipo de línea 38. 39. long=60; %km 40. Zc=200; 41. vel=300000; 42. tao=long/vel; 43. deltat=tao/10;

Page 150: Simulación de transitorios electromagnéticos de sistemas

132 Simulación de transitorios electromagnéticos mediante programación de GPUs

44. 45. prompt = 'Número de sistemas = enlaces '; 46. L=input(prompt); %número de enlaces 47. M =L; %número de sistemas 48. N=4; %Número de nodos 49. 50. if L*2>M*N 51. error('el número de sistemas excede la cantidad de nodos disponibles') 52. end 53. 54. %Defino P con todas las entradas cero, luego cambio algunos para definir 55. %enlaces. 56. 57. for i=1:M 58. P(:,:,i)=zeros(N,L*2); 59. end 60. 61. dispo = zeros(M, N); 62. c=1; %contador para recorrer todos los sistemas 63. k=randi([1,N]); %aleatorio para seleccionar nodo 64. h=1; %contador columna, para los +1 es de dos en dos columnas 65. for i=1:L 66. 67. if (dispo(c,k)==0) 68. P(k,h,c)=1; 69. dispo(c,k)=1; 70. 71. elseif dispo(c,k)~=0 72. while dispo(c,k)~=0 73. k=randi([1,N]); 74. end 75. P(k,h,c)=1; 76. dispo(c,k)=1; 77. end 78. dispo; 79. sist_UA(i)=c-1; %En CUDA los indices comienzan desde cero. 80. nod_UA(i)=k-1; 81. 82. c=c+1; 83. if c==M+1 84. c=1; 85. end 86. 87. k=randi([1,N]); 88. dispo; 89. h=h+2; 90. 91. end 92. 93. % columna 2 es para -1 y columna 1 es para +1 y así sucesivamente. Se llena cada dos 94. 95. %Debo asignar los -1 en sistema aleatorio para cada enlace. 96. 97. h=2; 98. c=randi([1,M]); 99. k=randi([1,N]); 100. s=1; 101. 102. for i=1:L 103. while c==s

Page 151: Simulación de transitorios electromagnéticos de sistemas

Anexo H. Código MATLAB para la generación aleatoria de sistemas eléctricos 133

104. c=randi([1,M]); 105. end 106. if dispo(c,k)==0 107. P(k,h,c)=-1; 108. dispo(c,k)=1; 109. elseif dispo(c,k)~=0 110. while dispo(c,k)~=0 111. k=randi([1,N]); 112. c=randi([1,M]); 113. while c==s 114. c=randi([1,M]); 115. end 116. 117. end 118. P(k,h,c)=-1; 119. dispo(c,k)=1; 120. end 121. sist_UB(i)=c-1; 122. nod_UB(i)=k-1; 123. h=h+2; 124. k=randi([1,N]); 125. c=randi([1,M]); 126. 127. s=s+1; 128. if s==M+1 129. s=1; 130. end 131. 132. %como evitar que dos enlaces lleguen al mismo nodo, se crea variable s 133. %pues el +1 fue asignado de sistema en sistema en orden, c puede ser 134. %cualquier sistema menos el correspondiente a s 135. 136. 137. end 138. 139. %Matrices usadas para Zalpha considero que el primer sistema es tipo A y el 140. %resto tipo B 141. for i=1:M 142. if i==1 143. a(:,:,i)=invA*P(:,:,i); 144. else 145. a(:,:,i)= invB*P(:,:,i); 146. end 147. end 148. %Calculo de Z 149. Z=diag(ones(L*2,1)*Zc); 150. 151. %Cálculo de Zalpha 152. Zalpha1= zeros(L*2,L*2); 153. for i=1:M 154. Zalpha1= P(:,:,i)'*a(:,:,i)+Zalpha1; 155. end 156. Zalpha =Zalpha1 + Z; 157. invZalpha=inv(Zalpha); 158. 159. for i=1:M 160. Pprima(:,:,i)=P(:,:,i)'; 161. end 162.

Page 152: Simulación de transitorios electromagnéticos de sistemas

134 Simulación de transitorios electromagnéticos mediante programación de GPUs

163. for i=1:M 164. Pabs(:,:,i)=abs(P(:,:,i)); 165. end 166. 167. param=[M L N Zc tao]; 168. fileID = fopen('param.txt','w'); 169. fprintf(fileID, '%f\n',param); 170. fclose(fileID); 171. 172. fileID = fopen('invA.txt','w'); 173. for i=1:N 174. for j=1:N 175. fprintf(fileID,'%f\n', invA(i,j)); 176. end 177. 178. end 179. fclose(fileID); 180. 181. 182. fileID = fopen('invB.txt','w'); 183. for i=1:N 184. for j=1:N 185. fprintf(fileID,'%f\n', invB(i,j)); 186. end 187. end 188. fclose(fileID); 189. 190. fileID = fopen('P.txt','w'); 191. for i=1:M 192. for j=1:N 193. for k=1:L*2 194. fprintf(fileID,'%f\n', P(j,k,i)); 195. end 196. end 197. end 198. fclose(fileID); 199. 200. fileID = fopen('Pprima.txt','w'); 201. for i=1:M 202. for j=1:L*2 203. for k=1:N 204. fprintf(fileID,'%f\n', Pprima(j,k,i)); 205. end 206. end 207. end 208. 209. fileID = fopen('Pabs.txt','w'); 210. for i=1:M 211. for j=1:N 212. for k=1:L*2 213. fprintf(fileID,'%f\n', Pabs(j,k,i)); 214. end 215. end 216. end 217. fclose(fileID); 218. 219. fileID = fopen('invZalpha.txt','w'); 220. for i=1:L*2 221. for j=1:L*2 222. fprintf(fileID,'%f\n', invZalpha(i,j));

Page 153: Simulación de transitorios electromagnéticos de sistemas

Anexo H. Código MATLAB para la generación aleatoria de sistemas eléctricos 135

223. end 224. end 225. fclose(fileID); 226. 227. fileID = fopen('sist_UA.txt','w'); 228. for i=1:L 229. fprintf(fileID,'%f\n', sist_UA(i)); 230. end 231. 232. fclose(fileID); 233. 234. 235. fileID = fopen('sist_UB.txt','w'); 236. for i=1:L 237. fprintf(fileID,'%f\n', sist_UB(i)); 238. end 239. 240. fclose(fileID); 241. 242. fileID = fopen('nod_UA.txt','w'); 243. for i=1:L 244. fprintf(fileID,'%f\n', nod_UA(i)); 245. end 246. 247. fclose(fileID); 248. 249. fileID = fopen('nod_UB.txt','w'); 250. for i=1:L 251. fprintf(fileID,'%f\n', nod_UB(i)); 252. end 253. 254. fclose(fileID); 255. 256. fileID = fopen('dispo.txt','w'); 257. for i=1:M 258. for j=1:N 259. fprintf(fileID,'%f\n', dispo(i,j)); 260. end 261. end 262. fclose(fileID); 263. 264. %Grafica de resultados de CUDA 265. %Espera mientras el código se ejecuta en C++, el usuario deberá presionar 266. %cualquier tecla 2 veces para continuar 267. toc 268. disp("Pausa, ejecute el código en CUDA y luego regrese, debe presionar cualquier tecla 2 veces") 269. for ind = 1:2 270. pause; 271. disp(ind); 272. end 273. 274. deltat=tao/10; 275. kmax=35e-3/deltat; 276. 277. fidi = fopen('C:\Users\Quartas\Google Drive\Maestría\Trabajo con Javier Herrera\Tareas\16. Códigos

a validar\Mate_aleatorio2\Mate_aleatorio2_CUDA\Mate_aleatorio2\CUDA_Ulinea.txt','r'); 278. U = textscan(fidi, '%f %f'); 279. 280. fclose(fidi);

Page 154: Simulación de transitorios electromagnéticos de sistemas

136 Simulación de transitorios electromagnéticos mediante programación de GPUs

281. 282. uA=U1; 283. uB=U2; 284. 285. h=1; 286. for i=1:L 287. for j=1:kmax 288. U_A(i,j)=uA(h); 289. U_B(i,j)=uB(h); 290. h=h+1; 291. end 292. end 293. 294. t2=[0:deltat:35e-3-deltat]; 295. figure(1) 296. plot(t2, U_A(1,:)) 297. title('\bfVoltaje vs Tiempo CUDA U_A1') 298. xlabel('Tiempo') 299. ylabel('Voltaje') 300. 301. figure(2) 302. plot(t2, U_B(1,:)) 303. title('\bfVoltaje vs Tiempo CUDA U_B1') 304. xlabel('Tiempo') 305. ylabel('Voltaje')

Page 155: Simulación de transitorios electromagnéticos de sistemas

Bibliografía

[1] J. Bélanger, P. Venne, and J. Paquin, “The What, Where and Why of Real-Time

Simulation,” Planet RT, pp. 37–49, 2010.

[2] V. Jalili-Marandi and V. Dinavahi, “Large-scale transient stability simulation on

graphics processing units,” 2009 IEEE Power Energy Soc. Gen. Meet. PES ’09, pp.

1–6, 2009, doi: 10.1109/PES.2009.5275844.

[3] P. Zhang, J. R. Martí, and H. W. Dommel, “Network Partitioning for Real-time Power

System Simulation,” Network, pp. 1–6, 2005.

[4] J. Martinez-Velasco, “Real time simulation technologies in Engineering,” Wiley-IEEE

Press, p. 648, 2014.

[5] S. Cieslik, “GPU Implementation of the Electric Power System Model for Real-Time

Simulation of Electromagnetic Transients,” no. January 2013, pp. 1–6, 2013, doi:

10.2991/iccsee.2013.279.

[6] L. Chen, Y. Chen, Y. Xu, and Y. Gong, “A novel algorithm for parallel electromagnetic

transient simulation of power systems with switching events,” 2010 Int. Conf. Power

Syst. Technol., no. 1, pp. 1–7, 2010, doi: 10.1109/POWERCON.2010.5666405.

[7] F. A. Moreira, J. R. Martí, L. C. Zanetta, and L. R. Linares, “Multirate simulations with

simultaneous-solution using direct integration methods in a partitioned network

environment,” IEEE Trans. Circuits Syst. I Regul. Pap., vol. 53, no. 12, pp. 2765–

2778, 2006, doi: 10.1109/TCSI.2006.882821.

[8] J. Martí and L. Linares, “OVNI: Integrated software/hardware solution for real-time

simulation of large power systems,” Proc. PSCC, no. June, pp. 1–7, 2002.

[9] M. A. Tomim, T. De Rybel, and J. R. Martí, “Extending the Multi-Area Thévenin

Equivalents method for parallel solutions of bulk power systems,” Int. J. Electr. Power

Energy Syst., vol. 44, no. 1, pp. 192–201, 2013, doi: 10.1016/j.ijepes.2012.07.037.

[10] F. A. Moreira, J. R. Martí, L. C. Zanetta, and L. R. Linares, “Multirate simulations with

simultaneous-solution using direct integration methods in a partitioned network

environment,” IEEE Trans. Circuits Syst. I Regul. Pap., vol. 53, no. 12, pp. 2765–

2778, 2006, doi: 10.1109/TCSI.2006.882821.

Page 156: Simulación de transitorios electromagnéticos de sistemas

138 Simulación de transitorios electromagnéticos mediante programación de GPUs

[11] NVIDIA, “Procesamiento paralelo CUDA,” 2017. [Online]. Available:

http://www.nvidia.es/object/cuda-parallel-computing-es.html.

[12] NVIDIA, “Aceleración computacional,” 2017. [Online]. Available:

http://www.nvidia.es/object/gpu-computing-es.html.

[13] Y. Tang, L. Wan, and J. Hou, “Full electromagnetic transient simulation for large

power systems,” Glob. Energy Interconnect., vol. 2, no. 1, pp. 29–36, 2019, doi:

10.1016/j.gloei.2019.06.004.

[14] T. Strasser, “Real-Time Simulation Technologies for Power Systems Design ,

Testing , and Analysis,” IEEE Power Energy Technol. Syst. J., vol. 2, no. 2, pp. 63–

73, 2015.

[15] S. Santoso, Fundamentals of Electrical Power Quality. Austin: The University of

texas at Austin, 2012.

[16] R. Bansal and P. T. Manditereza, “Fault Analysis,” Power Syst. Prot. Smart Grid

Environ., pp. 33–79, 2019, doi: 10.1201/9780429401756-2.

[17] K. Karimi, N. G. Dickson, and F. Hamze, “A Performance Comparison of CUDA and

OpenCL,” no. 1, 2010.

[18] T. Sörman, “Comparison of Technologies for Computing on Graphics Processing

Units,” 2016.

[19] NVIDIA, “Cuda C Programming Guide,” Program. Guid., no. September, pp. 1–261,

2015.

[20] C.-W. HO, A. E. Ruehli, and P. A. Brennan, “The Modified Nodal Approach to

Network Analysis,” Proc. IEEE, vol. 73, no. 3, pp. 485–487, 1975, doi:

10.1109/PROC.1985.13168.

[21] J. Martinez-Velasco, Coordinación de aislamiento en redes eléctricas de Alta y Extra

Alta tensión, 1st ed. Matrid: McGraw-Hill, 2007.

[22] L. H-restrepo, G. Caicedo, and F. Castro-aranda, “Modelos de línea de transmisión

para transitorios electromagnéticos en sistemas de potencia,” vol. 16, no. 1, pp. 21–

32, 2008.

[23] H. W. Dommel and W. S. Meyer, “Computation of Electromagnetic Transients,” Proc.

IEEE, vol. 62, no. 7, pp. 983–993, 1974, doi: 10.1109/PROC.1974.9550.

[24] EEUG, “ATP/EMTP,” 2020. [Online]. Available: https://www.emtp.org/.

[25] A. Gray and J. Perry, “Learn CUDA in an Afternoon : Hands-on Practical Exercises

Getting Started with CUDA,” pp. 1–5.

Page 157: Simulación de transitorios electromagnéticos de sistemas

Bibliografía 139

[26] C. Pérez Represa, J. M. Cámara Nebreda, and P. L. Sánchez Ortega, “Introducción

a la programación en CUDA,” Univ. Burgos, 2016.

[27] J. Larkin, “GPU fundamentals,” NVIDIA, 2016.

[28] J. Luitjens, “CUDA Streams: Best Practices and Common Pitfalls,” GPU Technol.

Conf., 2014.

[29] NVIDIA, “CUDA Enabled GPUs,” 2020. [Online]. Available:

https://developer.nvidia.com/cuda-gpus.