Вы находитесь на странице: 1из 239

UNIVERSIDAD DE BUENOS AIRES

Facultad de Ingeniera

TESIS DE GRADO

Sistema de Control de Flujos a Lazo Cerrado Mediante


Controlador Lineal Basado en Imagenes

Presentada por:
Pablo Daniel Roca

Director: Dr. Ing. Guillermo Artana

Octubre de 2013
Resumen

El presente trabajo estudia los sistemas de control de flujos a lazo cerrado de naturaleza predic-
tiva. En particular, se centra el estudio en la definicion de un sistema basado en imagenes que
controle el flujo de un fluido en el experimento prototipo del escurrimiento sobre un cilindro, con
posibilidad de implementacion en tiempo real. Se elige este escenario por tratarse de una expe-
riencia de oscilacion autosostenida por el flujo, y por lo tanto, con caractersticas fuertemente
no lineales que deben ser sobrellevadas por el controlador lineal en desarrollo.
Se define un sistema que estabiliza la estela del cilindro utilizando el procesamiento de
imagenes. A tal fin, se realiza una simulacion numerica sobre el flujo del fluido a traves del
cilindro. Se inyectan trazadores pasivos en el escurrimiento y se utilizan imagenes para medir la
concentracion e identificar el modelo AutoRegressive with eXtra inputs (ARX) que caracteriza al
sistema fsico. Se implementa un algoritmo Generalized Predictive Controller (GPC) que calcula
la actuacion necesaria para estabilizar la estela a traves del agregado de cantidad de movimiento
tangencial a las paredes del cilindro mediante la inyeccion de plasma.
El algoritmo de control es ejecutado desde el codigo de simulacion que queda a la espera de
una respuesta para continuar con el procesamiento. Para ello, se crean interfaces de comunicacion
entre el simulador (Fortran) y el controlador (C++ y Matlab). Tanto el diseno de la experiencia
como el desarrollo de los algoritmos se realiza con el objetivo de ser utilizados en un entorno
de ejecucion real en trabajos futuros. Se realizan algunos avances en el uso de General-Purpose
Computing on Graphics Processing Units (GPGPU) mediante CUDA C/C++ sobre sectores del
codigo que requieren alto paralelismo a fin de aumentar la performance en posibles escenarios
de tiempo real.
La efectividad del sistema de control y del algoritmo creado son comprobadas mediante di-
versas simulaciones numericas para distintos escenarios. Los datos experimentales son analizados
y expuestos junto a posibilidades de mejora para trabajos futuros.

Palabras clave: control, fluidos, lazo cerrado, feedback, ARX, GPC, cilindro, estela, identifica-
cion de sistemas, simulacion, controlador lineal, no-linealidades

1
Indice general

1 Introduccion 8

2 Sntesis del Estado del Arte 11

2.1 Introduccion 12

2.2 Teora de Control 13


2.2.1 Fundamentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.2 Estrategias de Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.2.1 Controlabilidad, Observabilidad y Estabilidad . . . . . . . . . . . . . . 17
2.2.3 Evolucion de la Teora Control . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.3.1 Teora Control Clasica . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2.3.2 Teora Control Moderno . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.4 Control Predictivo Basado en Modelo . . . . . . . . . . . . . . . . . . . 19

2.3 Control y Modelos de Fluidodinamica 24


2.3.1 Generalidades de Modelos de Fluidodinamica . . . . . . . . . . . . . . . 24
2.3.2 Modelos Basados en la Fsica . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3.3 Modelos de Caja Negra . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.3.3.1 Identificacion de Sistemas . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.3.2 Efectos de No-Linealidades . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.3.4 Avances en Aplicaciones de Control en el Dominio de la Fluidodinamica 30

2.4 Trabajo Interdisciplinario y Aspectos Computacionales 32


2.4.1 Discretizacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.4.2 Tiempos de Procesamiento . . . . . . . . . . . . . . . . . . . . . . . . . 33

2.5 Problematica a Resolver 34

2.6 Conclusiones 35

3 Solucion y Diseno de la Experiencia 36

3.1 Introduccion 37

3.2 Sistema Fsico Bajo Estudio 38


3.2.1 Estela de un Cilindro . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.1.1 Desprendimiento de Vortices . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.1.2 Regmenes de Escurrimiento . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2.2 Actuacion sobre el Cilindro . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2.2.1 Actuadores por Rotacion . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2.2.2 Actuadores de Plasma . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.2.3 Aplicaciones Particulares de Control sobre el Cilindro . . . . . . . . . . 43

3.3 Diseno y Objetivos de la Experiencia 45


3.3.1 Configuracion y Dimensiones . . . . . . . . . . . . . . . . . . . . . . . . 45
3.3.2 Sensores y Actuadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.3.3 Sntesis y Objetivos de la Experiencia . . . . . . . . . . . . . . . . . . . 49

3.4 Algoritmo de Identificacion del Sistema 51

3.5 Algoritmo de Control a Lazo Cerrado 54

3.6 Conclusiones 58

4 Ensayo Experimental 59

4.1 Introduccion 60

4.2 Mallado de la Experiencia 61


4.2.1 Tamano de Celdas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.2.2 Paso de Tiempo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

4.3 Simulacion de la Experiencia 65


4.3.1 Configuracion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.3.1.1 usini1.f90 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.3.1.2 usclim.f90 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.3.2 Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

4.4 Comunicacion con el Sistema de Control 75


4.4.1 Lenguajes Utilizados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.4.2 Interaccion entre Modulos . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.4.3 Implementacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

4.5 Identificacion del Sistema 81


4.5.1 Entrenamiento del Sistema . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.5.2 Implementacion del Algoritmo . . . . . . . . . . . . . . . . . . . . . . . 83
4.5.3 Verificacion del Modelo ARX . . . . . . . . . . . . . . . . . . . . . . . . 84

4.6 Sistema de Control a Lazo Cerrado 90


4.6.1 Implementacion del Algoritmo . . . . . . . . . . . . . . . . . . . . . . . 90
4.6.1.1 Inicializacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
4.6.1.2 Iteracion de Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
4.6.2 Resultados de Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
4.6.2.1 Analisis de Energa y RMS de las Fluctuaciones en la Estela . . . . . . 97
4.6.3 Pruebas de Robustez . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

4.7 Conclusiones 106


5 Conclusiones Generales y Perspectivas 108

5.1 Conclusiones Generales 109

5.2 Trabajos Futuros 111

Apendices 112

A Resena de Control de Fluidos 113


A.1 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
A.2 Evolucion Historica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

B Mallado de la Experiencia 115


B.1 Detalle del Mallado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
B.2 Efectos de Cambios Bruscos en la Malla durante la Simulacion . . . . . 117

C Verificacion de la Identificacion del Sistema 119


C.1 Ajuste en Implementacion Matlab . . . . . . . . . . . . . . . . . . . . . 119
C.2 Ajuste y Tiempos en Implementacion C++ . . . . . . . . . . . . . . . . 119

D Avances Experimentales para Trabajos Futuros 122


D.1 Control Adaptativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
D.2 Control con Modelo ARX de Orden Elevado . . . . . . . . . . . . . . . 123
D.3 Captura de Imagenes Mediante Camaras Digitales . . . . . . . . . . . . 125
D.3.1 PixelFly qe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
D.3.2 Pulnix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
D.3.3 SpeedCam Mini Vis e2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

E Publicaciones 127
E.1 Anales de la AFA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
E.2 Physics of Fluids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

F Codigos Fuente 152


F.1 Extension del Mallado 2D a 3D . . . . . . . . . . . . . . . . . . . . . . . 152
F.2 Conversion del Mallado Irregular a una Grilla Cartesiana . . . . . . . . 155
F.2.1 chrCleanFolderIfExists.m . . . . . . . . . . . . . . . . . . . . . . . . . . 155
F.2.2 chrComputeAverage.m . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
F.2.3 chrComputeVorticityAverageForGeoXY.m . . . . . . . . . . . . . . . . 156
F.2.4 chrExtractBinaryHeader.m . . . . . . . . . . . . . . . . . . . . . . . . . 156
F.2.5 chrFindFiles.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
F.2.6 chrFindFilesAndComputeAverage.m . . . . . . . . . . . . . . . . . . . . 157
F.2.7 chrGetAmountOfHeadingCharacters.m . . . . . . . . . . . . . . . . . . 157
F.2.8 chrReadBinaryContent.m . . . . . . . . . . . . . . . . . . . . . . . . . . 157
F.2.9 chrReadBinaryGeo.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
F.2.10 chrReadVelocity2D.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
F.2.11 chrWriteBinaryContent.m . . . . . . . . . . . . . . . . . . . . . . . . . . 158
F.2.12 chrWriteCaseFile.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
F.2.13 geoComputeIntersectionArea.m . . . . . . . . . . . . . . . . . . . . . . . 159
F.2.14 geoGetBoundingRectsForDelta.m . . . . . . . . . . . . . . . . . . . . . . 159
F.2.15 geoTransformContentToNonXY.m . . . . . . . . . . . . . . . . . . . . . 160
F.2.16 geoTransformContentToXY.m . . . . . . . . . . . . . . . . . . . . . . . 160
F.2.17 geoTransformMeshToXYGrid.m . . . . . . . . . . . . . . . . . . . . . . 160
F.2.18 polygonArea.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
F.2.19 polygonClip.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
F.3 Calculo de Energa Cinetica y RMS de las Fluctuaciones . . . . . . . . 163
F.3.1 plotEnergy.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
F.3.2 processEnergy.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
F.3.3 processRmsCriteria.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
F.3.4 computeReynoldsTensor.m . . . . . . . . . . . . . . . . . . . . . . . . . 167
F.3.5 computeRMS.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
F.3.6 selectIntegrationCoordinates.m . . . . . . . . . . . . . . . . . . . . . . . 167
F.4 Simulacion en Code Saturne . . . . . . . . . . . . . . . . . . . . . . . . 167
F.4.1 usini1.f90 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
F.4.2 usclim.f90 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
F.5 Identificador del Sistema en Matlab . . . . . . . . . . . . . . . . . . . . 189
F.5.1 lfd arx.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
F.5.2 lfd compare.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
F.5.3 lfd training actuation.m . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
F.5.4 lfd training actuation gaussian.m . . . . . . . . . . . . . . . . . . . . . . 192
F.5.5 lfd training actuation multiple gaussian.m . . . . . . . . . . . . . . . . . 192
F.5.6 lfd training actuation pulse.m . . . . . . . . . . . . . . . . . . . . . . . 192
F.5.7 lfd training actuation ramp.m . . . . . . . . . . . . . . . . . . . . . . . 192
F.6 Controlador en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
F.6.1 main.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
F.6.2 Config.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
F.6.3 configuration control.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
F.6.4 configuration training.txt . . . . . . . . . . . . . . . . . . . . . . . . . . 196
F.6.5 Constants.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
F.6.6 Controller.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
F.6.7 Controller.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
F.6.8 Logger.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
F.6.9 lfd control lagrange init.m . . . . . . . . . . . . . . . . . . . . . . . . . 202
F.6.10 lfd control lagrange.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
F.6.11 MatlabExecutor.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
F.6.12 MatlabExecutor.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
F.6.13 Matrix.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
F.6.14 Parser.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
F.6.15 Parser.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
F.6.16 SaturneCommunicator.h . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
F.6.17 SaturneCommunicator.cpp . . . . . . . . . . . . . . . . . . . . . . . . . 211

G Codigos Fuente de Avances Experimentales 212


G.1 Pruebas de Concepto de Captura de Imagenes . . . . . . . . . . . . . . 212
G.1.1 PixelFly qe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
G.1.2 Pulnix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
G.1.3 SpeedCam Mini Vis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
G.2 Pruebas de Concepto de Ident. de Sist. en CUDA C/C++ y C++/GSL 214
G.2.1 main.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
G.2.2 arxEngine/ArxSystemIdentification.h . . . . . . . . . . . . . . . . . . . 216
G.2.3 arxEngine/ArxSystemIdentification.cpp . . . . . . . . . . . . . . . . . . 216
G.2.4 common/Matrix.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
G.2.5 common/CULAContext.h . . . . . . . . . . . . . . . . . . . . . . . . . . 229
G.2.6 common/CULAContext.cpp . . . . . . . . . . . . . . . . . . . . . . . . 229
G.2.7 common/Exception.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
G.2.8 common/Exception.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
G.3 Pruebas de Concepto de Controlador Adaptativo . . . . . . . . . . . . . 231
G.3.1 lfd control init.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
G.3.2 lfd control.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Agradecimientos

A Claudia, por todo el tiempo compartido... y el que resta por compartir.


A mi familia, por estar siempre presente.
A los integrantes del Laboratorio de Fluidodinamica (UBA), por la colaboracion constante,
desinteresada y oportuna que siempre me prestaron. En particular, un agradecimiento especial
a Guillermo Artana, Ada Cammilleri y Thomas Duriez que participaron activamente de las
experiencias y me guiaron en el desarrollo del presente trabajo.
A mis companeros de trabajo, por todo lo que aprend y crec profesionalmente durante estos
anos.
A mis companeros de facultad, por compartir las dificultades que presenta carrera.
A mis companeros del Proyecto Nahual, por demostrar que la computacion tambien sirve
para cambiar algo.
A mis companeros de ayudanta, por introducirme al mundo de la docencia.
A los que creen en la ciencia como camino para el desarrollo.
A la gente tenaz y trabajadora.

Pablo Daniel Roca, Octubre de 2013

7
Parte 1

Introduccion

8
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

El control del movimiento de fluidos es una disciplina de gran importancia para la industria
y la ciencia. Los objetivos de la teora clasica de control como el seguimiento de un valor de
referencia o el rechazo frente a perturbaciones son considerados en aplicaciones especficas de
fluidodinamica como la reduccion del arrastre o la supresion de inestabilidades que guardan gran
interes por su uso practico.
El presente trabajo introduce avances en el ambito del control de la dinamica de los fluidos
presentando un sistema de control automatico lineal que pueda ser utilizado en sistemas no
lineales y que posibilite su uso fuera de condiciones de laboratorio. A tal fin, se utilizan conceptos
de teora de control e identificacion de sistemas que en conjunto permiten definir un algoritmo
generico, independiente de la experiencia.
Se escoge al escurrimiento sobre un cilindro como caso de estudio para realizar las simula-
ciones pertinentes debido a su importancia como experiencia prototipo para diversos fenomenos
de fluidodinamica. Asimismo, su naturaleza de oscilador autosostenido asegura la existencia
de marcadas no-linealidades que permiten verificar la bondad del controlador lineal propuesto.
Mediante consideraciones generales de control de fluidos, se establece el objetivo de control y
esquema de actuacion particulares para dicho escenario. Se propone la inyeccion de filamentos
de un trazador pasivo, como el humo, que permite demarcar la estela del cilindro y detectar sus
cambios mediante el diagnostico por imagenes. El objetivo de control establece que el escalar
inyectado adopte un patron determinado que garantice la disminucion de fluctuaciones cercanas
al cilindro.
Si bien existen trabajos de control de fluidos orientados a experiencias de control con retroali-
mentacion (tambien conocido como control a lazo cerrado) utilizando imagenes, la obtencion de
informacion se realiza mediante tecnicas de Particle Image Velocimetry (PIV) donde se calcula
la velocidad instantanea de partculas entre dos imagenes sucesivas. En contraposicion, el me-
canismo propuesto permite obtener la informacion del estado instantaneo del sistema mediante
una unica imagen. Se reduce as el tiempo de transferencia de datos necesarios para la toma de
decisiones y la necesidad de incurrir en calibracion de complicados sistemas de camara, lasers
potentes para iluminar la zona ni tecnicas complejas de inyeccion de trazadores. Esto ampla la
posibilidad de uso en experiencias reales.
El controlador desarrollado utiliza tecnicas de lazo cerrado estudiadas en Teora de Control
para permitir un ajuste automatico de la actuacion. Este esquema requiere una representacion
matematica adecuada, en este caso mediante la identificacion del sistema con un modelo de
caja negra. Ya establecidos el marco de control y modelizada la experiencia se aplican tecnicas
de generacion de plasma en las paredes del cilindro para controlar la estela. Este metodo es
estudiado en el campo del control de fluidos por los beneficios potenciales de su rapido tiempo
de respuesta y carencia de componentes mecanicos.

A continuacion se describen las partes que componen el presente trabajo y su organizacion.


La Parte 2 resume el estado del arte de la Teora de Control y del Control de Fluidos junto
con los conceptos generales que resultan indispensables para el trabajo en el area. Se focaliza
en los controladores predictivos y los escenarios de control a lazo cerrado debido al impacto que
tienen en aplicaciones reales. De igual forma, se hace mencion a las tecnicas de modelado pun-
tualizando los esquemas de caja negra y la identificacion de dichos sistemas en base al muestreo
de experiencias. Por ultimo, se especifican ciertos aspectos computacionales importantes en el
Control de Fluidos y se define la problematica a resolver.
La Parte 3 sintetiza los conceptos aplicados en el escurrimiento de un flujo sobre el cilindro
y las aplicaciones del estudio de dicha experiencia en la vida cotidiana. Luego, se establecen las

9
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

particularidades del modelo a simular y se especifican los algoritmos disenados para la identifi-
cacion del sistema y su control.
La Parte 4 incluye el detalle de la simulacion numerica de la experiencia, la definicion del
mallado, la identificacion del sistema, el desarrollo del controlador y su integracion con el si-
mulador. Los resultados de la aplicacion de control son expuestos y analizados para validar la
efectividad del controlador. Luego, se realizan distintas pruebas con escenarios no ideales, es
decir con la existencia de ruido, para analizar robustez del algoritmo. De la misma forma se
verifica la adaptabilidad del controlador realizando simulaciones con cambios en las condiciones
de entrada que definen la dinamica de la experiencia.
Por ultimo, la Parte 5 resume las conclusiones del estudio realizado y sintetiza las perspectivas
futuras y posibilidades de mejora.
Los distintos apendices incluyen el codigo fuente utilizado para la identificacion de siste-
ma y el algoritmo de control as como las aplicaciones y scripts auxiliares empleadas para el
analisis de la informacion. Se incluyen ademas avances experimentales en sistemas de control
adaptativos, empleo de camaras digitales y paralelizacion en General-Purpose Computing on
Graphics Processing Units (GPGPU) sobre identificacion de sistemas. Aunque estos casos no
forman parte del controlador utilizado, muestran grandes ventajas de implementacion e incre-
mentos de performance importantes respecto de los algoritmos usuales y, por lo tanto, deben
ser tenidos en cuenta en experiencias real-time del sistema de control. Como agregado, se in-
cluyen las publicaciones presentadas en la los Anales de la Asociacion Fsica Argentina (AFA)
y American Institute of Physics para la revista Physics of Fluids producto de la investigacion
realizada durante el presente trabajo.

10
Parte 2

Sntesis del Estado del Arte

11
2.1 Introduccion

El presente captulo introduce los conceptos fundamentales y definiciones de la Teora de


Control as como posibles clasificaciones para controladores de acuerdo a su tipo. A su vez, se
realiza una sntesis sobre la evolucion y etapas claves del control: Teora de Control Clasica
y Teora de Control Moderno, haciendo principal hincapie en el Control Predictivo Basado en
Modelo.
Una vez definidos los conceptos de control, se exploran las diferentes tecnicas de modelizacion
para fenomenos de fluidodinamica tanto para aquellos basados en la fsica como los de caja negra.
Se profundiza en estas ultimas y se ejemplifica su uso en distintas situaciones de control de fluidos
reforzando el impacto de las no-linealidades en la identificacion del sistema y posterior uso del
modelo.
Luego, se hace foco en la sub-rama de Control de Fluidos. Se presentan los objetivos mas
comunes, aplicaciones conocidas y la importancia del trabajo interdisciplinario junto con los
aspectos computacionales mas importantes para el area.
Por ultimo, se brinda una descripcion de la problematica a tratar incluyendo una breve
definicion de la experiencia prototipo elegida a modo de ejemplo.

12
2.2 Teora de Control

2.2.1. Fundamentos
El termino control posee dos acepciones basicas: comprobar algun suceso o dominarlo. En
la Teora de Control, el primer significado se entiende como la actividad de verificar o validar
que cierta representacion matematica de un suceso fsico tiene un comportamiento satisfactorio
frente a la realidad. La segunda acepcion implica la capacidad de actuar o llevar a cabo ciertas
decisiones para garantizar el comportamiento del suceso en cuestion. En otras palabras, controlar
supone la aplicacion de cierto plan para conseguir un orden determinado.
La teora de control involucra el trabajo interdisciplinario de matematicos con especialistas en
diversas ramas de la ingeniera tales como la mecanica, electronica, aeronautica e informatica.
Se estudia la forma de influir sobre la dinamica de distintos sistemas mediante tecnicas de
medicion, comparacion, calculo y correccion. Los conceptos basicos de la teora de control como
retroalimentacion, fluctuaciones y optimizacion pueden encontrarse en situaciones cotidianas y
fenomenos naturales que, lejos de los planteos matematicos y complejidades ingenieriles, resultan
simples e intuitivos [21, 1].
El concepto de retroalimentacion (o feedback ) es utilizado en la teora de la evolucion de
las especies, propuesta por C. Darwing (1805-1882), para explicar el mecanismo de seleccion a lo
largo de perodos largos de tiempo que resulta responsable de la evolucion. De la misma forma,
el feedback resulta importante en modelos estadsticos de epidemiologa y poblacion como el
propuesto por V. Volterra (1860-1940) para explicar las variaciones en la poblacion de peces a
lo largo del tiempo y su relacion con la cantidad de predadores con los que comparten el habitat
[8]. Dicho modelo, que es uno de los primeros intentos exitosos de explicacion de poblacion
biologica, presenta un mecanismo natural de feedback para mantener el equilibrio de ambas
especies y determinar como inciden los cambios de poblacion de una sobre la tasa de crecimiento
de la otra.
Otro concepto clave de la teora de control es la necesidad de fluctuaciones que refiere a la
dificultad de imponer un estado deseado de forma brusca. Por el contrario, resulta mas eficiente
aceptar los cambios graduales y oscilaciones que presentan el sistema en estudio. Por ejemplo,
el conductor de un vehculo en movimiento conoce los riesgos de un frenado brusco y opta en su
lugar por reducir la velocidad aplicando el freno de forma incremental hasta detener el vehculo.
Los primeros registros de esta idea pertenecen al ingeniero mecanico H.R. Hall al identificar al
modelo de control de presion en maquinas de vapor como una aplicacion de la ley economica de
oferta y demanda [29]:

Es curioso el hecho que mientras economistas polticos reconocen que por la accion de
la ley de oferta y demanda deben existir fluctuaciones, esto no es generalmente reconocido por
mecanicos en sus esfuerzos de controlar el motor a vapor. El objetivo de los ingenieros mecanicos,
como el de los economistas polticos, no debe ser el deshacerse de todas las fluctuaciones [...] sino
disminuirlas tanto como sea posible, aun dejandolas lo sufientemente altas como para mantener

13
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

su poder regulatorio.

Por ultimo, el concepto de optimizacion resulta clave para entender el objetivo del control.
Esta idea es estudiada como rama matematica cuya metodologa base es definir las variables del
problema, un funcional que se desea maximizar o minimizar expresado en dichas variables y las
tecnicas que permitan encontrar la condicion optima para el planteo. Este esquema es aplicado
en actividades diarias como ajustar el gas de una cocina para mantenerlo al mnimo necesario
que garantice el hervor del agua o determinar la cantidad de riego que requiere un cultivo para
conseguir la humedad necesaria sin desperdiciar agua.
Dado que las primeras aplicaciones formales de control se centran en problemas de ingeniera,
la terminologa empleada hereda palabras utilizadas en la industria. A continuacion se definen
conceptos basicos de amplio uso en la teora de control [47] que son referidos en el presente
trabajo:

Sistema: combinacion de componentes que interactuan con un cierto objetivo. El concepto de


sistema puede ser aplicado a elementos fsicos (como los sistemas biologicos o fenome-
nos fsicos) o a nociones abstractas (como conceptos economicos, flujos de informacion o
algoritmos de procesamiento).

Proceso: conjunto progresivo de operaciones o cambios tanto naturales como artificiales que
se suceden de alguna forma y cuyos efectos determinan un resultado o fin. Se puede decir
que toda sucesion de operaciones que desea ser controlada es un proceso.

Planta: dispositivo fsico, pieza de algun equipamiento o conjunto de maquinas que opera con
algun objetivo particular que se desea controlar.

Actuador: elemento fsico de la planta que frente a una senal indicada por el controlador puede
operar sobre la fsica que rige el proceso.

Controlador: sistema encargado de determinar la necesidad de actuacion para conseguir cierto


objetivo de proceso e informar dicha senal al actuador.

Variables Controladas: cantidad o condicion que es medida y controlada. Tambien se las


conoce como senales de salida del proceso a controlar o, simplemente, salidas.

Variables Manipuladas: cantidad o condicion que puede ser modificada por el controlador
y cuyos cambios rigen la operacion del actuador. Tambien se las conoce como senales
de entrada del proceso o, simplemente, entradas. Se trata de variables independientes
del proceso que pueden incidir en las variables dependientes, que usualmente se desean
controlar.

Perturbaciones: senales que perjudican la senal de salida de un sistema. Pueden ser generadas
dentro del sistema (internas) o fuera del mismo (externas).

2.2.2. Estrategias de Control


Una posible clasificacion de la estrategia de control elegida para un sistema depende de
la forma en que utiliza energa para su actuacion. La division mas basica que plantea esta
clasificacion separa aquellos sistemas cuyos actuadores utilizan energa para poder forzar al
proceso en estudio de aquellos que no emplean energa. Se habla entonces de sistemas de control
activo y pasivo respectivamente [22].

Captulo 2.2. Teora de Control 14


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

El control pasivo consiste en la disposicion de elementos fsicos dentro de la planta que


modifican la dinamica del proceso bajo estudio, acercandola a una configuracion deseada. Este
esquema de actuacion posee un interes menor para la teora de control dada la complejidad
en modificar el objetivo de control durante su funcionamiento. Esta circunstancia presenta un
limitante importante para el uso del controlador ya que un cambio en el objetivo esperado
(aunque se trate de un pequeno ajuste en el valor deseado) suele requerir la redefinicion del
actuador, colocacion del nuevo dispositivo fsico y sucesivas pruebas y ajustes para obtener la
nueva dinamica deseada.
Por otro lado, el control activo utiliza energa para forzar las condiciones del fluido mediante
distintas tecnicas de actuacion. Este tipo de control acepta la posibilidad de variar parametros
de actuacion como la intensidad o frecuencia dentro de ciertos lmites en pleno ciclo de control,
es decir, sin necesidad de practicar cambios ni ajustes sobre los actuadores. Los ajustes pueden
hacerse manualmente, siendo un humano el que indica la variacion, o mediante un controlador
que reaccione frente a los cambios que presente el sistema. Esta flexibilidad permite definir siste-
mas de control con cierto grado de inteligencia, esto es, con la posibilidad de variar la actuacion
de forma dinamica sin indicaciones humanas. Se definen entonces dos tipos de estrategias de
control activo: el predeterminado y el reactivo. La Teora de Control se centra en esquemas de
control reactivo mediante el estudio de distintos algoritmos, la medicion de variables de planta
y la construccion de dispositivos de actuacion que mejor ajustan al proceso bajo estudio.
A continuacion se resume esta caracterizacion de controladores considerando su fuente de
energa [22]:

Pasivo: no emplean energa externa al proceso bajo estudio. Las posibilidades de modificaciones
sobre el controlador son, por lo general, limitadas.

Activo: utilizan energa externa para activar los actuadores y controlar el proceso por lo que
son mas versatiles.

Predeterminado: los parametros de actuacion son fijos e independientes del estado del
proceso. Admite ajustes mediante cambios manuales aplicados por el humano.
Reactivo: la actuacion es definida por un algoritmo de control que reacciona frente a
mediciones realizadas sobre variables del proceso y del entorno.

El sistema de control puede utilizar sensores dispuestos en la planta para tener informacion
sobre las variables controladas o fuera de ella para adquirir datos que permitan modelar las
perturbaciones que recibe el sistema. Por ejemplo, en un sistema de control de temperatura
para un horno de cocina, suponiendo que la variable controlada es la temperatura del centro
del horno, un sensor de temperatura colocado en las paredes internas puede proveer (o aproxi-
mar) dicho valor. Por el contrario, un sensor de temperatura colocado en el exterior del horno
provee informacion importante sobre las perturbaciones que sufre el sistema. En escenarios de
control pasivo o predeterminado esta informacion no es usada por el controlador pero resulta
indispensable para plantear un control reactivo.
Al emplear algoritmos en controladores reactivos se utiliza el concepto de ciclo (bucle o loop)
para referirse a los pasos repetitivos que ejecuta el controlador estando en regimen. En este
contexto, si se utilizan valores presentes o pasados de las variables controladas para calcular la
actuacion de los proximos pasos se habla de un ciclo de control con feedback. Por el contrario, si se
utiliza informacion sobre las perturbaciones externas (que posiblemente aun no hayan afectado
a la planta) se trata de un ciclo de control con prealimentacion (feedforward ). El primer caso es
el mas comun y recibe la denominacion de control a lazo cerrado (closed-loop control ) debido al
dibujo esquematico que lo representa (Fig. 2.2.2). En contraposicion, se suele hablar de control

Captulo 2.2. Teora de Control 15


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

por lazo abierto (open-loop control ) para los casos de control predeterminado, donde no existe
lazo.
Esto da lugar a una clasificacion de acuerdo al ciclo de control que se resume a continuacion:
Lazo Abierto (open-loop): guarda relacion con el control activo predeterminado en el sentido
de que una vez definida la actuacion se requiere la intervencion humana para modificarla
(Fig. 2.2.1).
Lazo Cerrado (closed-loop): tambien conocido como ciclo con retroalimentacion (feedback )
ya que utiliza informacion sobre el estado del sistema para plantear acciones correctivas
respecto de los valores de referencia deseados (Fig. 2.2.2).
Con Prealimentacion (feedforward ) se emplea informacion del entorno del sistema para ajus-
tar la actuacion y anticipar los efectos de las perturbaciones sobre la planta (Fig. 2.2.3).

Figura 2.2.1: Esquema de control a lazo abierto. No se utiliza informacion sobre el estado del sistema para
determinar la actuacion.

Figura 2.2.2: Esquema de control a lazo cerrado. Se utiliza feedback del sistema bajo estudio para determinar las
diferencias que existen respecto de los valores de referencia esperados. Con este error respecto de lo esperado, el
controlador calcula los valores de entrada que deberan corregir la salida.

Figura 2.2.3: Controlador feedforward. Se utiliza informacion sobre las perturbaciones para prealimentar al con-
trolador y actuar de forma anticipada a que los efectos sean notorios en la salida del sistema.

Captulo 2.2. Teora de Control 16


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

En el ejemplo de horno con temperatura automatica, un posible sistema de control a lazo


abierto recibe del humano la temperatura esperada y activa el sistema de calefaccion a cierta
intensidad precalculada. Un sistema de control a lazo cerrado, por el contrario, activara la cale-
faccion con una intensidad regulada por la diferencia entre la temperatura de referencia deseada
y la medida en el interior del horno. A medida que esta diferencia disminuye, la intensidad
de calefaccion converge a un valor pero, en caso de aparecer un cambio brusco en la medicion
(por ejemplo, al introducir un producto congelado que reduce la temperatura), el sistema ajusta
nuevamente la actuacion. Por ultimo, se puede pensar en un sistema que vara la intensidad de
calefaccion dependiendo de la temperatura de referencia y de la temperatura exterior al horno,
entregando mayor calor en das fros pero mediante un calculo predefinido, independiente de la
temperatura real del interior del horno.

2.2.2.1. Controlabilidad, Observabilidad y Estabilidad


En el caso particular del control a lazo cerrado, resultan importantes las propiedades de con-
trolabilidad, observabilidad y estabilidad. Si bien es posible encontrar una definicion matematica
apropiada para estos terminos respecto de las ecuaciones de estado del sistema controlador [72],
resulta de suma utilidad comprender la naturaleza de cada uno desde un punto de vista intui-
tivo. La controlabilidad determina si todos los modos del sistema pueden ser influenciados
por el controlador de forma arbitraria. Se trata de una propiedad tanto del estado del sistema
como del sistema de actuacion. De forma mas especfica se puede hablar de la controlabilidad
de salida que indica el control de las variables de salida del sistema independientemente de si
puede controlar variables de estado intermedias o no. La observabilidad esta relacionada con
la habilidad del sistema de sensado para medir los cambios de estado de forma confiable. El
sistema es observable si se puede determinar el estado en base a las mediciones de las salidas y
los valores conocidos de las entradas. Como ejemplo de sistema con observabilidad limitada se
puede suponer el caso de una olla a presion hogarena con indicadores de temperatura pero sin
sensores de presion y, por lo tanto, no es posible observar el conjunto de estados del sistema. La
estabilidad se asemeja a la controlabilidad pero en este caso exige unicamente que los modos
no estables puedan ser controlados. Esta diferenciacion permite indicar en que casos un sistema
estabilizable puede ser suficiente o cuando es necesario un sistema controlable debido a que los
modos estables poseen un papel importante en la respuesta final y se los desea manipular.

2.2.3. Evolucion de la Teora Control


A lo largo de los anos, la evolucion de la teora de control denota distintas etapas en cuanto a
madurez y enfoque de las tecnicas aplicadas. Durante ese avance continuo, se pueden identificar
dos tendencias que prevalecen y que presentan diferencias notorias respecto a los objetivos del
control: la Teora de Control Clasica y la Teora de Control Moderna.
Si bien existen estudios de control anteriores a la formalizacion de la teora, se trata de
experiencias muy diversas y basadas en el empirismo. Con la revolucion industrial aparece la
necesidad de maquinas automaticas y se acelera la investigacion sobre estos metodos [21]. La
invencion del regulador de presion del motor a vapor por parte de J. Watt (1736-1819) en 1769 fija
un caso de estudio de suma importancia que permite delinear las bases teoricas del control en los
anos subsiguientes. El escenario de control es dominado entonces por el ambito industrial hasta
la decada de 1940, donde los conflictos belicos enfocan la mayor parte del esfuerzo cientfico de
control en balstica y desarrollo aereo y naval. Ya finalizando la decada, la aparicion del termino
cybernetics (cibernetica) para referirse al estudio de control y comunicaciones en animales y
maquinas marca un hito importante en el desarrollo de la teora de control. Fue el matematico

Captulo 2.2. Teora de Control 17


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

N. Wiener (1894-1964) quien introduce el termino en 1948 como resultado de diversos trabajos
en ciencia cognitiva pero influenciado por los avances de la epoca en tecnicas de comunicacion,
mecanica estadstica y computacion junto a su relacion con procesos de aprendizaje, lenguajes,
informacion, sistemas auto-organizados entre otros campos de la ciencia. Al afirmar que las
maquinas eran sistemas capaces de aprender (o learning machines) al igual que los animales
[68] se ampla el horizonte de aplicaciones para la teora de control. Los nuevos ambitos de
aplicacion -entre los que se encuentra la inteligencia artificial, automatismo, ciencias de la vision,
teora de la conversacion o neurociencia- otorgan grandes expectativas a futuro aun en nuestros
das. La computacion toma un rol fundamental en este nuevo campo que frente a necesidad
de precision numerica, manejo de volumenes importantes de datos y velocidad en el calculo,
evoluciona cambiando sus expectativas de uso de una compleja maquina calculadora hacia el
ambito natural para sistemas de proposito especfico.

2.2.3.1. Teora Control Clasica


La Teora de Control Clasica centra su estudio en tecnicas en el dominio de la frecuencia.
Este enfoque utiliza tecnicas provenientes de los avances matematicos propuestos por Laplace
(1749-1827), Fourier (1768-1830) y Cauchy (1789-1857) para el analisis de sistemas Lineales
e Invariantes en el Tiempo (LTI) [47, 49]. A tal efecto se definen las variables dependientes
del tiempo y(t) y u(t) para referirse a la salida y entrada del sistema respectivamente. Si bien
es posible conocer la relacion entre dichas variables respecto del tiempo, se define la funcion
transferencia del sistema segun
Y (s)
H(s) =
U (s)
donde Y (s) es la transformada de Laplace de la salida y U (s) es la transformada de Laplace de
la entrada. Esta funcion es equivalente a la transformada de la respuesta del sistema al impulso
(h(t)) y, por lo tanto, caracteriza al sistema si este es LTI [47]. Para sistemas LTI con variables
de salida y entrada unicas (single-input, single-output o SISO), se puede utilizar H(s) junto con
propiedades de la transformada de Laplace y tecnicas graficas (diagramas de Bode, diagramas
de polos y ceros, lugar de las races, entre otras) [61] para determinar la respuesta del sistema
a distintas senales de entrada y variaciones de frecuencias. Estos mecanismos fueron usados de
forma exhaustiva en comunicaciones y electronica para la solucion de problematicas particulares
de las redes de comunicacion de larga distancia que se establecen durante la primer mitad del
siglo XX.
La rama de automatizacion y control industrial mostro grandes avances en sus aplicaciones
al incorporar el controlador Proporcional-Integral-Derivativo (PID) que aplica feedback sobre las
variables controladas en su valores actuales y pasados. Este controlador a lazo cerrado emplea
un componente proporcional (P) al error instantaneo, una parte integral (I) que aporta respecto
de la acumulacion de error por sobre o por debajo de la referencia y un elemento derivativo (D)
que entrega sensibilidad ajustando la actuacion en base a la velocidad con que vara el error
(Fig. 2.2.4). Este tipo de controlador sigue siendo de gran utilidad al igual que el concepto de
funcion de transferencia sobre el que se basa. Sin embargo, al aumentar la necesidad de controlar
situaciones de multiples variables de entrada y salida (multiple-input, multiple-output o MIMO)
donde las variables estan ligadas entre s, los procedimientos de la Teora Clasica se mostraron
por demas engorrosos [61, 47] dando lugar a nuevos mecanismos.

Captulo 2.2. Teora de Control 18


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 2.2.4: Esquema de un controlador a lazo cerrado PID. Se puede observar el efecto individual del error, su
integral y su derivada en el dominio del tiempo sobre la actuacion del controlador.

2.2.3.2. Teora Control Moderno


En contraste con la Teora Clasica, la Teora de Control Moderno realiza sus planteos basicos
en el dominio del tiempo y sobre sistemas MIMO con un manejo matricial en la matematica
de control que otorga transparencia sobre la multiplicidad de variables. Fue R. Kalman (1930-)
quien introdujo el concepto de estado como entidad matematica que intercede entre entradas y
salidas permitiendo la existencia de feedback multiple entre las variables de forma natural. Se
define entonces el estado de un sistema dinamico segun [24]:

El estado de un sistema dinamico es un conjunto de cantidades fsicas cuya especificacion


(en ausencia de excitaciones externas) determina por completo la evolucion del sistema.

Este concepto enfatiza la existencia de una estructura interna al sistema y la nocion de


causalidad de su dinamica. Para un sistema de dimensiones finitas la representacion del estado
esta dada por una ecuacion diferencial vectorial de dimensiones finitas tal que:

x(t) = Ax(t) + Bu(t)


y(t) = Cx(t)

donde x(t) es el vector de variables internas del sistema tambien conocido como vector de
estado, u(t) es el vector de las variables manipuladas e y(t) es el vector de variables controladas.
Las matrices A, B y C describen las interconexiones en la dinamica del sistema. Usando esta
representacion, Kalman formalizo las nociones de controlabilidad y observabilidad empleandolas
en la propuesta de una ley de control con feedback de la forma:

u(t) = K x(t)

dondeR la matriz de feedback, K, debe ser determinada para minimizar cierta funcion objetivo

J = 0 (xT Qx + uT Ru)dt siendo Q y R matrices de pesos constantes. Una vez determinada
K, se asume que no vara y por este motivo se habla de feedback estatico. Este esquema de
controlador es conocido como Linear Quadratic Gaussian (LQG) y establece las bases para los
nuevos algoritmos de esta etapa de la Teora de Control.

2.2.4. Control Predictivo Basado en Modelo


El campo del control predictivo fue concebido en el ambiente industrial durante la decada
de 1970 como respuesta para automatizacion de plantas qumicas, de energa y refineras al

Captulo 2.2. Teora de Control 19


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

esquema clasico de control PID. Los motivos principales para la investigacion de nuevas tecnicas
se pueden encontrar en las necesidades economicas fijadas por la industria y de difcil aplicacion
en los algoritmos de control clasicos:

Posibilidad de trabajo tan cercano a las restricciones como sea posible (usualmente vincu-
lado con la maximizacion del empleo de recursos industriales)

Minimizacion de la variabilidad (que pretende evitar la disparidad en la calidad de pro-


ductos)

El controlador LQG presentado en 1960 es considerado pionero en el uso de ciertos conceptos


predictivos en controladores pero, aun demostrando buenos resultados en el campo de procesos
no lineales, no tuvo aceptacion masiva por la industria. Una de las razones mas importantes
de la poca penetracion de mercado reside en barreras culturales con la comunidad industrial
que no vieron practicos a los nuevos conceptos de control y prefirieron continuar con estrategias
clasicas que les resultaban mas naturales [51]. Por el contrario, los avances en la teora de
control en la decada de 1970 que culminan en fundamentos del control predictivo resultaron de
facil entendimiento y adaptables a la problematica industrial:

Uso de un modelo que permita predicciones sobre las salidas futuras.

Minimizacion de una funcion objetivo mediante actuacion activa.

Ventana temporal del proceso que toma en cuenta las variables controladas y manipuladas
dentro de cierto horizonte de prediccion.

Los nuevos algoritmos de control provenientes de la inversion industrial entregan peso teorico
en los conceptos de prediccion y suceden al LQG con mayor exito. El primer caso es provisto por
J. Richalet (1936-) con Model Predictive Heuristic Control (MPHC o tambien conocido como
IDCOM debido al primer sistema de software que lo adopto) que utiliza un modelo discreto
de respuesta al impulso finito para describir la relacion entre entradas y salidas. Este modelo
es conocido como Finite Impulse Response (FIR) y relaciona y(t) con u(t) mediante ciertos
coeficientes de peso, hi , que deben ser determinados. La representacion matematica en tiempo
discreto de dicho modelo es:
XN
y(k) = hi u(k i)
i=1

El modelo elegido vincula cierto paso del tiempo k de la salida unicamente con la entrada
de hasta N pasos de tiempo previos. La determinacion de las hi se realiza mediante algoritmos
de estimacion que requieren un ajuste constante mediante comparacion con mediciones reales
de la planta[51]. Se utiliza al ciclo de control como punto para corregir un modelo que requiere
revalidacion continua por ser inevitablemente imperfecto [53].
Quizas el aporte conceptual mas importante de este tipo de control es la trayectoria de
referencia (Fig. 2.2.5) que define el camino deseado para los estados futuros de la planta. Este
camino, es interpretado como el comportamiento deseado de la planta convergiendo al valor de
referencia final. Calculando la trayectoria deseada se puede determinar la actuacion necesaria
para cada paso y entender la necesidad de un mecanismo de fluctuacion para evitar cambios
bruscos del estado y sus complicaciones. Por ultimo, este esquema enfatiza la relacion Accion
Comportamiento que, incorporando experiencia de campo y conocimientos sobre el proceso
en estudio, se puede extender a Comportamiento Deseado Accion Comportamiento
[53].

Captulo 2.2. Teora de Control 20


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 2.2.5: Posible trayectoria de referencia para la variable controlada (CV) en su camino para alcanzar la
referencia final (Set-point). Se asume que se posee la informacion pasada y del paso de tiempo actual (n) que
permite predecir la salida del proceso h pasos hacia el futuro gracias a un modelo matematico preestablecido (Sm ).
Definiendo el grado de aceptacion para la diferencia de error entre el proceso y el Set-point ((n)) o la variacion
del proceso (p) h pasos en el futuro, se puede calcular el valor de variable manipulada (MV) necesario (basada
en Richalet, 2009) [53].

En los anos subsiguientes aparecen nuevos sistemas de control entre los que se destacan Dy-
namic Matrix Control (DMC) y Shell Multivariable Optimizing Control (SMOC) por los avances
conceptuales que aplicaron al MPHC. El DMC, introducido en 1980, mantiene un esquema si-
milar al MPHC pero modela al sistema mediante la respuesta al escalon en lugar del impulso y
provee tratamiento de restricciones a las variables controlada (aunque no es incluido de forma
organica sino agregado ad-hoc) [44]. El esquema SMOC, presentado en 1988 como un puente
entre modelos en espacio de estados y los algoritmos MPC, permite incluir restricciones sobre
variables de salida agregandolas a la funcion objetivo. En efecto, esto es posible para restriccio-
nes debiles (tambien llamadas soft) y para el establecimiento de un valor de referencia (setpoint)
donde se minimiza la violacion penalizando en la funcion objetivo, pero no para restricciones
duras (hard ) que requieren un tratamiento particular (Fig. 2.2.6).

Captulo 2.2. Teora de Control 21


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 2.2.6: Tipos de restricciones en las salidas. Tomando el caso de una unica salida, se grafica su magnitud
(eje vertical) a lo largo del tiempo (eje horizontal) junto con los valores restringidos (zonas rayadas). Se puede
observar el efecto directo de las restricciones la salida para el caso hard y el impacto en la funcion objetivo para
los casos soft y setpoint (basado en Qin, 2003) [51].

A pesar del exito de las nuevas generaciones de controladores predictivos ninguno de ellos
poda ser catalogado como de proposito general y ser aplicados tanto en situaciones de planta
simples como en sistemas complejos. En particular, estos ultimos suelen requerir el ajuste fino de
los parametros del controlador que resulta muy sensible frente a los supuestos sobre el orden del
modelo y el tiempo de respuesta al control (o dead-time). En particular, el dead-time representa
la demora entre una modificacion en la variable manipulada y la aparicion de los primeros efectos
en la variable controlada.
En 1987 se introduce el Generalized Predictive Controller (GPC) [14, 15] que se centra en
calcular los valores de actuacion futuros tales que luego de cierto tiempo no sufran variaciones,
es decir se estabilicen en torno de cierto valor definitivo de actuacion. Para ello se predicen las
salidas futuras en respuesta a las entradas calculadas a traves de una funcion objetivo y un
horizonte de tiempo que limita las variaciones.
Esta tecnica trajo beneficios en terminos de robustez y simplicidad de calculo, a la vez que
proveyo un mecanismo de auto-ajuste (o self-tuning) que permite al algoritmo sobreponerse a

Captulo 2.2. Teora de Control 22


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

errores en supuestos sobre orden o dead-time. GPC utiliza el modelo Controlled Auto-Regressive
and Integrated Moving-Average(CARIMA) que vincula valores actuales y pasados de entradas
y salidas segun:

y(k) + a1 y(k 1) + +ana y(k na)


=b1 u(k 1) + + bnb u(k nb)
(k) (k 1) (k nc)
+ + c1 + + cnc

donde (k) es un variable estocastica que modela el error por perturbaciones, es el operador
de diferencia y na, nb, nc son lmites de prediccion para las salidas, entradas y perturbaciones.
Este modelo resulta apropiado para aplicaciones industriales donde las perturbaciones son no
estacionarias como en el caso de saltos de escalon aleatorios o movimientos Brownianos [14]
y es uno de los motivos por los que el GPC demuestra mayores areas de aplicacion que sus
competidores.

Captulo 2.2. Teora de Control 23


2.3 Control y Modelos de Fluidodinamica

El area de control de fluidos es una disciplina de gran crecimiento durante los ultimos anos
debido a su importancia en el ambito academico y de ciencia aplicada. La maduracion relativa
de las distintas disciplinas cientficas contribuyo en esta rama proveyendo conocimientos clave
y descubrimientos que permiten predecir un futuro muy promisorio [7].
En busca de una definicion general del control de fluidos, es posible citar a J. Flatt (1961)
que brinda una descripcion para el control en fenomenos de capa lmite que se puede extender
facilmente a otros escenarios:

El control de capa lmite incluye cualquier mecanismo o proceso a traves del cual la capa
lmite del flujo de un fluido es forzada a comportarse de forma diferente de como normalmente
se hubiera desarrollado [...]

Pero la necesidad de forzar la condicion de un fluido esta asociado a un objetivo predefinido


en terminos de las propiedades del fluido. La manipulacion del arrastre, sustentacion, separacion
de la capa lmite, repegado de la capa lmite, retardo de la transicion son considerados objetivos
particulares del control de fluidos que pueden combinarse de forma simultanea o en distintas
facetas de una experiencia para definir el objetivo general de control. El Apendice A incluye una
breve resena de la evolucion historica sobre esta rama de la fluidodinamica as como el detalle
de objetivos particulares de control de flujos.
Como se explica en el Captulo 2.2, un sistema de control a lazo cerrado requiere de un
modelo para predecir estados futuros de las variables. A continuacion se detallan las distintas
tecnicas de modelizacion utilizadas en fluidodinamica y los avances de aplicacion conseguidos en
el area.

2.3.1. Generalidades de Modelos de Fluidodinamica


En su acepcion mas generica, un modelo es una representacion de algun concepto en termi-
nos de elementos que existen en cierta area de estudio. El area de estudio determina el lenguaje
con el cual se describe el objeto en cuestion y por lo tanto, la informacion que se puede extraer
de el.
M. Minsky (1927-) brinda una definicion concisa para modelo [45]:

Un objeto A es un modelo del objeto A para el observador B, si B puede emplear A para


responder cuestiones que le interesan acerca de A.

De esta definicion se desprende una importante reflexion: el detalle del modelo respecto del
objeto depende del detalle de las observaciones que se pretendan realizar. Aun mas, el grado de
exactitud del modelo respecto del objeto modelado dependera de las necesidades del estudio.
Es conocido que el estudio de fenomenos fsicos requiere el uso intensivo de herramientas
matematicas. En este contexto, el empleo de modelos matematicos para representar sistemas

24
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

fsicos ha sido un arma de gran utilidad para su analisis y manipulacion


En el estudio de fluidodinamica, la importancia de los modelos reside principalmente en la
capacidad de predecir la respuesta de un flujo frente a condiciones definidas y como cambia
la respuesta al modificarse las condiciones. Si el modelo puede responder a estas preguntas,
sera posible estimar la actuacion necesaria para obtener determinado objetivo respecto del flujo.
Las ecuaciones de Navier-Stokes proveen de un modelo matematico completo sobre los
problemas de fluidodinamica. Sin embargo, la complejidad de resolucion que presenta el sis-
tema de ecuaciones que gobierna el fenomeno plantea la necesidad de aplicar simplificaciones
al modelo. Esto es debido a su no-linealidad y alto orden. Un esquema alternativo consiste en
inferir un modelo simplificado a partir de la observacion de un flujo particular y la adopcion de
suposiciones sobre su naturaleza. Existen basicamente dos estrategias para obtener modelos que
arreglen las observaciones mediante cierto patron: modelos basados en la fsica e identificacion
de sistemas.

2.3.2. Modelos Basados en la Fsica


Este tipo de modelos buscan una reduccion de orden sobre el modelo de ecuaciones de Navier-
Stokes utilizando una descomposicion modal. Una de las elecciones mas usuales es considerar
una descomposicion del tipo Proper Orthogonal Decomposition (POD) donde se identifican los
modos de mayor energa y se desechan aquellos que producen un menor impacto. Este esquema
plantea una descomposicion del campo de velocidades del flujo u(x, t) en modos espaciales y
temporales segun:
Xn
u(x, t) = ai (t)i (x)
i=1

donde las funciones i (x) representan los n modos espaciales y las ai (t) indican los coeficientes
temporales de cada modo. Los i (x) son obtenidos mediante la resolucion de un problema
de autovalores sobre un conjunto de observaciones de u(x, t) y definen una base ortogonal de
vectores.
El conjunto de ecuaciones del modelo de orden reducido es obtenida al utilizar los n elemen-
tos de la base en una una proyeccion de Galerkin sobre las ecuaciones de Navier-Stokes. Este
procedimiento provee un sistema de ecuaciones diferenciales ordinarias, compuesto de tantas
ecuaciones como modos retenidos luego del analisis inicial. Sin embargo, el sistema obtenido
puede divergir prematuramente o durante el perodo de entrenamiento por la anulacion del fac-
tor de amortiguamiento que ofrecen los modos mas altos y que fue suprimido por el truncado de
modos. Aunque este comportamiento presenta grandes restricciones, existen algunas estrategias
para evitarlo [3].
Los modos de POD usualmente exhiben multiples frecuencias y resulta difcil asociar su
estructura espacial con las caractersticas observables del flujo. Como consecuencia, distintos
autores se han preguntado sobre la correlacion de dichos modos con magnitudes fsicas medibles.
Dado que los modos POD no pueden ser asociados a estructuras coherentes del flujo en todos los
casos, la base de funciones utilizadas para la proyeccion puede no ser lo suficientemente amplia
para expresar las diversas condiciones del flujo. Se conocen esfuerzos recientes en mejorar la
calidad de la base y remediar esta limitacion [58].
Otro inconveniente de este esquema es la limitacion para incluir estmulos externos, tanto los
asociados como actuaciones de control como aquellos que resultan de perturbaciones autonomas
y fuerzan el estado del flujo. Dentro de las bondades del esquema POD sobresale la posibilidad
de definir facilmente la funcion objetivo del control. Cuando se desea minimizar las fluctuaciones
del flujo, es posible plantear la minimizacion del total de energa asociada a las fluctuaciones

Captulo 2.3. Control y Modelos de Fluidodinamica 25


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

sobre un sector del flujo. Esa magnitud es determinada con los coeficientes temporales de los
modos (llamados chronos) [10].
Alternativamente, existen los Modelos de Orden Reducido (Reduced Order Models o ROM)
que consideran los llamados modos globales, pero esta estrategia no presenta buenos resultados
para todas las situaciones [5]. Uno de los requerimientos mas restrictivos de los esquemas ROM
es la necesidad de disponer del campo de velocidades del flujo para generar el modelo. Desde el
punto de vista de las aplicaciones practicas, la obtencion del campo de velocidades en tiempo
real constituye un gran impedimento. Es por ello que este tipo de modelos se limita a simula-
ciones numericas o experiencias en tuneles de viento equipados con sistemas de Particle Image
Velocimetry (PIV) de mayor o menor complejidad. Incluso en estos casos existen problemas
asociados con la robustez del modelo frente a cambios en el dominio.

2.3.3. Modelos de Caja Negra


En contraposicion a los modelos basados en la fsica del problema, el esquema de identificacion
de sistemas utiliza modelos de caja negra que responden al sistema fsico. En este caso se
emplean tecnicas empricas y un conjunto de mediciones sobre la experiencia para elegir una
parametrizacion adecuada y determinar los parametros que mejor ajustan a los valores medidos.

AR
Una de las metodologas de identificacion de sistemas mas utilizadas se basa en relaciones
auto-regresivas (AutoRegressive o AR) entre los valores el estado del sistema en el tiempo actual
y pasados. El ejemplo mas simple de un modelo AR consta de la siguiente relacion entre variables:
p
X
y(k) = i y(k i)
i=1

donde y(k) representa la variable observable en el tiempo k, p es el horizonte de regresion y i


es un coeficiente de peso para el tiempo k i. El modelo tendra un buen ajuste si la relacion
fijada por los i existe en el sistema fsico y se mantiene a medida que avanza el paso de tiempo
k dentro de la ventana definida por los p coeficientes i . El modelo asume que no existe relacion
con variables para i > k o que la misma posee un i despreciable.

ARX
Otro ejemplo de modelo autorregresivo contempla la existencia de entradas externas al sis-
tema que condicionan el comportamiento de las variables observables del problema fsico en
estudio. Las entradas actuan como variables independientes del problema mientras que las sali-
das son dependientes o ligadas. En estos casos se habla de un modelo AutoRegresive with eXtra
inputs (ARX) que en contextos de econometra se conoce como AutoRegresive with eXogenous
variables [42]. Se plantea la siguiente relacion entre variables para este tipo de modelos:

y(k) + a1 y(k 1) + + aNa y(k Na ) =


b0 u(k) + b1 u(k 1) + + bNb u(k Nb )

que tambien puede expresarse como


Na
X Nb
X
y(k) + ai y(k i) = bi u(k i)
i=1 i=0

Captulo 2.3. Control y Modelos de Fluidodinamica 26


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

donde u(k) representa la variable externa independiente (en los sistemas bajo estudio sera la
variable de control), Na y Nb son los lmites de auto-regresion para los coeficientes ai y bi
respectivamente. En este modelo se admite la dependencia de y(k) respecto de u(k) para el
tiempo actual y tiempos pasados. Esta dependencia resulta evidente al despejar la salida del
tiempo actual (y(k)) y observar que para predecir dicho valor, es necesario contar con valores
previos de y, valores previos de u y el valor de u en el tiempo actual (u(k)).
Los ejemplos anteriores contemplan la existencia de variables de entrada y salida unicas; se
trata de sistemas SISO. Para modelos complejos, donde se define para cada paso de tiempo un
vector de estado que incluye los valores de una o mas variables observables junto con una o mas
variables de control, nos encontramos con sistemas MIMO. En este ultimo caso, las variables u e
y se transforman en vectores (un componente de u por cada entrada y un componente de y por
cada salida, para cada paso de tiempo). Sin cambios en la ecuacion, se la puede extender a la
forma matricial para representar ese esquema si entendemos a u(k), y(k) como vectores columna
y ai , bi matrices con dimensiones apropiadas.
Por ultimo, los coeficientes ai y bi se pueden agrupar utilizando una notacion reducida:
A(q)y(k) = B(q)u(k)
donde se definen las matrices de polinomios
A(q) = I + a1 q 1 + + aNa q Na B(q) = b0 + b1 q 1 + + bNb q Nb
siendo q 1 el operador de corrimiento:
q n f (k) = f (k n)
En todos los casos se debe entender la existencia de un termino de error e en cualquiera de
los lados de la igualdad que corrige las incertezas que provoca el modelo de caja negra. Este
modelo matematico admite una representacion por bloques que se puede observar en la Fig.
2.3.1.

Figura 2.3.1: Diagrama de bloques de un modelo ARX.

ARMAX
Una extension del modelo ARX se obtiene al considerar los efectos del ruido blanco y mo-
delarlo con una media movil. En este caso se plantea el mismo tratamiento que el recibido por
las entradas de control donde se entrega distinto peso al ruido originado en el tiempo actual
frente a tiempos pasados. Dicho peso se modela mediante una matriz de coeficientes (en este
caso C(q)) y utilizando conocimientos previos sobre el orden de magnitud del ruido que acepta
la experiencia. Este esquema se conoce como AutoRegressive with Moving Average and eXtra
inputs (ARMAX) y se define mediante la siguiente relacion entre variables:
A(q)y(k) = B(q)u(k) + C(q)e(k)

Captulo 2.3. Control y Modelos de Fluidodinamica 27


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

donde e(k) representa el valor de error o ruido para el tiempo k. Un posible diagrama de bloques
para este esquema puede observarse en la Fig. 2.3.2.

Figura 2.3.2: Diagrama de bloques de un modelo ARMAX.

En este caso decimos que el modelo contempla la dinamica de los errores y que estos poseen
un origen comun con las entradas u para afectar luego a la salida medida y segun puede verse en
el diagrama. Existen otros modelos de la misma naturaleza lineal y auto-regresiva que plantean
una fuente de errores en la medicion de y. Tambien resulta factible la modelizacion de errores en
ambos extremos del proceso con el agregado de una nueva variable de error y su correspondiente
matriz de coeficientes. Es importante remarcar que al aumentar la complejidad del modelo
a utilizar resulta mas difcil definir la configuracion de parametros apropiada para reflejar al
fenomeno en estudio. Por estos motivos es conveniente utilizar el modelo mas simple que otorgue
buenos resultados, escalando de forma progresiva en complejidad de ser necesario.

2.3.3.1. Identificacion de Sistemas


La identificacion de sistemas cobra gran relevancia como campo de estudio para la obtencion
de modelos de caja negra que representen fielmente el sistema fsico. El modelo elegido suele ser
predefinido en base a preconceptos o suposiciones sobre la experiencia y sus caractersticas. La
eleccion del tipo de modelo y sus parametros basicos como orden u horizontes de tiempo suele
fundamentarse en los conocimientos sobre el fenomeno pero aceptando que seran necesarios
ajustes posteriores en base a la exactitud que demuestre el modelo.
A su vez, es necesario definir las variables de estado a medir y determinar cuales se consideran
dependientes (outputs para modelos auto-regresivos) y cuales independientes (inputs). Luego, se
realiza un muestreo dentro del ambito de una experiencia controlada y el conjunto de vectores de
estado obtenidos son utilizados para estimar los parametros del modelo matematico que mejor
los ajustan. A tal fin, las tecnicas de estimacion de parametros suelen plantear la minimizacion
del error que se presenta entre el valor real medido y una prediccion de dicho valor mediante
el uso del modelo matematico. La tecnica de estimacion por cuadrados mnimos (Least Squares
Estimates o LSE) y sus variaciones son las de mayor aceptacion debido a caractersticas como
convergencia de la estimacion, estabilidad y robustez.
La aplicacion practica de estas tecnicas al campo del control de fluidos suele requerir de la
medicion del campo de velocidades del fluido en una etapa previa su uso en el control. Esta etapa
suele denominarse fase de entrenamiento y puede incluir la contemplacion de la experiencia fsica
para su posterior caracterizacion o la necesidad de aplicar cierta actuacion para forzar el flujo.

Captulo 2.3. Control y Modelos de Fluidodinamica 28


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Este ultimo caso permite obtener la relacion contemplada por los modelos ARX y ARMAX
entre los parametros de entrada y la salida. Es conveniente hacer uso de un amplio espectro
de frecuencia en la actuacion de entrenamiento para asegurar que las mediciones recolectadas
son significativas de la relacion entre entradas y salidas. El empleo de pulsos en la actuacion
sumada a la suposicion de linealidad del sistema debera permitir una correcta prediccion en
base a entrada de senales diversas, sin embargo no hay un criterio universalmente aceptado para
fijar caractersticas del pulso como duracion, amplitud, tiempo de descanso anterior y posterior,
etc.

2.3.3.2. Efectos de No-Linealidades


Un inconveniente conocido en las estrategias antes descritas es la suposicion de linealidad
del modelo. En efecto, los modelos de caja negra ejemplificados (ARX y ARMAX) son lineales
y asumen que el fenomeno que modelan posee caractersticas lineales o al menos, se puede
garantizar su linealidad dentro de un entorno de trabajo. La respuesta predictiva del modelo
de caja negra dejara de ser precisa fuera de ese entorno, mostrara grandes diferencias con el
fenomeno o divergira; dependiendo de el sistema fsico bajo estudio. Existen modelos de caja
negra no lineales entre los que se destacan las redes neuronales, Wavelets y Kernel Estimators
[42] que no seran abordados en el presente trabajo.

Amplificadores de Ruido y Osciladores Auto-sostenidos


Si bien el caracter no lineal de la mayora de los fluidos en estudio esta relacionado con
las no-linealidades presentes en las ecuaciones de Navier-Stokes, esto no afecta con la misma
intensidad a todos los fenomenos. En efecto, la naturaleza inherente del flujo estudiado define dos
clasificaciones basicas con grandes diferencias en las no-linealidades presentes: los amplificadores
de ruido y los osciladores auto-sostenidos.
Los amplificadores de ruido son altamente sensibles a las perturbaciones que son trasladadas
fuertemente al resto del sistema. En estas experiencias, la modelizacion de las fuentes de ruido e
incertezas resulta fundamental para capturar la dinamica del proceso y poder predecir el estado
futuro del sistema. Se puede reconocer sistemas amplificadores de ruido en varias aplicaciones
como la separacion de flujos de superficies planas, separacion de la capa lmite o problemas como
el salto por escalon.
Algunos flujos de naturaleza oscilatoria, por otro lado, presentan inestabilidades globales
que sostienen sus fluctuaciones y los vuelven poco sensibles a perturbaciones externas. En estos
contextos, el modelado de las perturbaciones no resulta tan importante como la captura de
la dinamica de las inestabilidades propias. En el proceso de suprimir dichas inestabilidades y
amortiguar el proceso oscilatorio se refuerzan las caractersticas no-lineales del sistema.

Control de Sistemas No-Lineales Mediante Modelos Lineales


Para captar la dinamica de los fenomenos en sistemas fuertemente no-lineales como los
osciladores auto-sostenidos, la eleccion mas natural es el uso de modelos no-lineales. Sin embargo,
las dificultades computacionales y los problemas para relacionarlos con la fsica del sistema suelen
reducir sensiblemente los beneficios de este esquema. En [31] se encuentra una discusion sobre
distintos acercamientos al control de flujos no-lineales con sistemas de control lineales. En el
caso particular del control de la estela de un cilindro, se proponen estrategias basadas en redes
neuronales [16]. Tambien es posible el uso de otras estrategias como algoritmos de identificacion
adaptativos o la estabilizacion del flujo de forma previa a la identificacion del sistema [11].

Captulo 2.3. Control y Modelos de Fluidodinamica 29


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

En cualquiera de los casos, es importante remarcar que la construccion de un modelo simple


que permita un control efectivo y el uso de leyes de feedback es mas importante que la precision
y la exactitud con que describen el fenomeno [31].
En ese sentido, la posibilidad de utilizar simples modelos lineales de caja negra como ARX
y ARMAX resulta por demas atractiva. Es posible encontrar esfuerzos en estudios de teora de
control que utilizan ARMAX como modelo del sistema [30]. Aunque esta eleccion entregara
un sistema mas robusto frente a la aparicion de ruidos, el empleo de control mediante ARX fue
ampliamente utilizado [4, 35, 36, 31] debido a la mayor simpleza y buenos resultados conseguidos.

2.3.4. Avances en Aplicaciones de Control en el Dominio de la


Fluidodinamica
En la actualidad, los mayores esfuerzos de investigacion estan dirigidos al control reactivo
por las perspectivas a futuro que presenta su flexibilidad. Esto no significa que las tecnicas de
control pasiva o activa predeterminada carezcan de utilidad. Al contrario, las estrategias de
control pasivas suelen tener una gran aceptacion para aplicaciones reales debido a su bajo costo
de diseno, construccion y mantenimiento.
En dispositivos de control pasivo, la accion es permanente y no se encuentra preparada
para el ajuste dinamico de los parametros de control durante la experiencia debido a su fuerte
vinculacion con la estructura original del experimento. Esta metodologa puede ser encontrada
en la colocacion de generadores de vortices [41, 27, 20], placas de separacion a lo largo de la lnea
central de la estela de un cilindro [54, 55] y cilindros de control de tamano menor al cilindro
controlado [9].
Respecto del control predeterminado, es sabido que la mayor parte del trabajo experi-
mental de control de fluidos fue realizado con este esquema de lazo abierto [17]. El monitoreo
de estos estudios frente a variaciones en los parametros de actuacion permitio obtener un buen
nivel de conocimiento sobre las dinamicas de los distintos fenomenos antes de emprender es-
tudios a lazo cerrado. Ejemplos tpicos de actuadores involucrados en este tipo de control son
los j ets pulsados sinteticos [27, 38], dispositivos mecanicos ajustables, cilindros rotantes [66] o
actuadores de plasma [18, 4, 46, 34, 56]. Es importante destacar que estas experiencias de control
pueden ser adaptadas y utilizar algoritmos de lazo cerrado gracias a las conclusiones obtenidas
durante su instrumentacion a lazo abierto.
En contraposicion al control predeterminado, el uso de control reactivo debera implicar
menores cantidades de energa empleada. Mas aun, debera permitir su aplicacion en un amplio
entorno de operaciones, dado que el controlador adapta su respuesta en pos de conseguir un
objetivo prefijado. Tanto los algoritmos de feedforward como los de feedback deben vincular los
valores de la salida medida en los sensores con la definicion de entradas para el actuador.
Se conocen trabajos a lazo cerrado con distintas tecnicas de actuacion y algoritmos de control.
Se tiene referencias sobre actuaciones de succion/soplado para contrarrestar la separacion del
flujo sobre una superficie plana [31] (ARX y control optimal lineal), transpiracion normal de
pared (mediante succion/soplado) para cancelar la interaccion con vortices incidentes [39] (ley
de control lineal sobre un arreglo de sensores), inyeccion de cantidad de movimiento para reducir
la separacion de la capa lmite en una superficie plana [30] (ARMAX y control LQG) y controlar
las fluctuaciones de presion en una cavidad de tonos mediante el movimiento mecanico de sus
bordes [35, 36] (ARX y control GPC). Se conocen ademas, escenarios de control aplicados a
la experiencia prototipo de cilindros. En esta lnea se han utilizado tecnicas como inyeccion de
sonido en las paredes de un cilindro para cancelar el desprendimiento de vortices mediante el
sensado del flujo de masa [32] (amplificacion y corrimiento de fase sobre medicion en sensor) y
actuadores piezoelectricos sobre cilindros flexibles [71] (control PID).

Captulo 2.3. Control y Modelos de Fluidodinamica 30


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

En todos los casos se trata de experiencias con controladores lineales con resultados
exitosos. Sin embargo, se debe remarcar que las experiencias sobre las que fueron comprobados
no guardan un caracter no-lineal fuerte, por tratarse de sistemas amplificadores de ruido, o tales
efectos son disminuidos por los rangos de amplitud o velocidad utilizados. Como agregado, los
efectos de excluir ciertas no-linealidades del modelo matematico del problema afectan el ajuste
de los parametros al igual que la definicion de una funcion objetivo como se describe en [30].
Por otro lado, se conocen casos exitosos de controladores no-lineales que implican dis-
tintos grados de complejidad. Como caso de baja complejidad se puede mencionar el control
mediante oscilaciones del cilindro para cancelar las estabilidades de su estela [64], donde se apli-
ca una ley de control no-lineal sobre las mediciones del sensor. Si bien se obtuvieron buenos
resultados, se trata de un esquema particular al caso bajo estudio y de difcil extension a otras
experiencias. Como ejemplo de mayor complejidad se conocen aplicaciones exitosas de redes
neuronales aplicadas mediante rotaciones del cilindro [26]. En esta situacion se utilizan estruc-
turas de decision que no se pueden relacionar con las magnitudes fsicas conocidas del problema,
agregando una complicacion extra para adaptar el sistema a otras experiencias.

Captulo 2.3. Control y Modelos de Fluidodinamica 31


2.4 Trabajo Interdisciplinario y Aspectos
Computacionales

Trabajo Interdisciplinario
Durante siglos, el trabajo cientfico baso su progreso en la especializacion bajo diversas dis-
ciplinas. La especializacion permitio aislar las distintas problematicas y conseguir una mejor
preparacion de los investigadores en cuanto a tecnicas y conocimientos particulares. Pero a me-
dida que las ramas cientficas se hicieron mas y mas complejas, el enfoque de trabajo se torno mas
estrecho y aislado de las otras. Esta tendencia que permitio enormes avances cientficos duran-
te el siglo XX, resolviendo preguntas de gran complejidad e interes, se encuentra en retroceso
dando lugar al auge del trabajo interdisciplinario. Sin embargo, el cambio de enfoque requiere
modificaciones en los habitos de trabajo y mentalidad de los investigadores que no siempre son
aceptadas. En algunos casos se trata de complicaciones en la implementacion mientra que en
otras son preconceptos o barreras mentales donde frases como fuera de mi area resultan por
demas frecuentes [7].
Este nuevo enfoque no solo favorece la rama de control de fluidos sino que sin el sera impo-
sible pensar en un crecimiento sostenido de la misma. Las nuevas competencias requieren cono-
cimientos de areas tales como la fluidomecanica, matematica, ingeniera de control, electronica
y computacion que deben cooperar y coordinar esfuerzos. En este sentido, es necesario reforzar
la necesidad de un enfoque amplio, del trabajo interdisciplinario y de un lenguage comun entre
las partes.

Aspectos Computacionales
Uno de los aspectos computacionales mas importantes del control de fluidos recae en la
gran capacidad de procesamiento que requieren tanto las simulaciones como las experiencias de
laboratorio. En efecto, la discretizacion de la dinamica de un fluido se expresa con la presion y
el campo de velocidades instantaneo para los puntos que lo conforman. Esto implica una gran
cantidad de valores para describir cada experiencia que fijan de forma indirecta los tiempos de
computo necesarios. En este contexto, la discretizacion temporal y espacial elegidas determinan
las dimensiones del problema mediante un muestreo con cierta peridicidad y la recoleccion de
cierta cantidad de puntos. En estas condiciones, resulta importante evaluar los requisitos de
procesamiento de los algoritmos de control aplicados.

2.4.1. Discretizacion
La teora de fluidodinamica tiene sus bases en el estudio de funciones continuas en el tiempo.
Gran parte de su bibliografa y avance teorico se sustenta en formulaciones de tiempo continuo
que contrastan con el enfoque de tiempo discreto propuesto en Teora de Control [61].
Lejos de pretender un analisis detallado del impacto que posee la discretizacion de senales
continuas y el efecto que tiene sobre su espectro en frecuencias [49, 48], es importante entender

32
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

a la discretizacion como una necesidad de la rama de control dentro de la fluidodinamica. El


factor mas importante en este sentido esta dado por el empleo de control reactivo y la fuerte
necesidad de utilizar computadoras o microcontroladores para definir sus bucles de control.
Estos dispositivos no admiten el manejo de magnitudes continuas sino que requieren algun tipo
de conversion analogico-digital de las senales de entrada y salida.
En este contexto, el desarrollo de los distintos esquemas de control de fluidos requiere la
discretizacion de las ecuaciones de Navier-Stokes, en tiempo continuo, consideradas basicas para
el estudio de la fluidodinamica [31]. Como alternativa a la discretizacion de ecuaciones, es posible
optar por modelos de caja negra basados en muestras del proceso bajo estudio que establecen
de forma natural el entorno de trabajo digital para algoritmos de control [31].

2.4.2. Tiempos de Procesamiento


Es importante destacar que muchas de las experiencias sobre las que fueron ideadas las
distintas estrategias que propone la teora de control poseen tiempos caractersticos elevados y
una cantidad reducida de puntos de observacion. Esto se observa claramente en las experiencias
que demuestran la efectividad del controlador GPC [15] donde el tiempo de muestreo es 1s con
tiempos de respuesta de 160 muestras. Si bien se verifico la efectividad de las estrategias de
control y de los sistemas implementados bajo dichos entornos, existen ordenes de magnitud de
diferencia respecto de los fenomenos usuales de fluidodinamica. Trabajos recientes de control de
turbulencias muestran perodos de 0,67s para el fenomeno caracterstico de la experiencia, en
este caso el desprendimiento de vortices en un cilindro [18]. Otra implementacion de laboratorio,
que implica velocidades de muestreo de menor perodo para captar la dinamica del sistema
refiere perodos caractersticos de 0,098s con frecuencias de muestreo de 1Khz para obtener un
controlador a lazo cerrado del tipo PID para la reduccion del efecto de arrastre sobre un cuerpo
romo [6].
Estas caractersticas limitan la cantidad de informacion que puede ser procesada en tiempo
real para garantizar que el controlador actue dentro de los lapsos de tiempo previstos.
Varios investigadores han sugerido que hasta que se observen mejoras en las condiciones de
computo y la relacion con el costo asociado, no sera factible el uso de sistemas de control con
tales caractersticas [22]. En este sentido, el avance en el poder de computo obtenido durante los
ultimos anos tanto en supercomputadoras como en equipos convencionales alcanzo capacidades
que permiten pensar procesamiento de informacion de fluidos en tiempo real. Las mejoras en
velocidad de procesamiento, espacios de almacenamiento y capacidades de concurrencia fueron
capitalizadas en mejores herramientas para simular y tratar casos no de flujos no estacionarios.
De todas formas, esta expansion de horizontes aun no permite resolver el conjunto de aplicaciones
que las distintas ramas de ingeniera requieren [17].

Captulo 2.4. Trabajo Interdisciplinario y Aspectos Computacionales 33


2.5 Problematica a Resolver

El presente trabajo centra su analisis en el estudio de un sistema de control lineal a lazo


cerrado sobre sistemas de fluidodinamica no lineales. Esto plantea avances en el area de control
de fluidos debido a la simplicidad de los modelos lineales frente a los no lineales y la falta de
resultados positivos a la fecha sobre su uso en sistemas netamente no lineales. Aunque se tiene
referencia de trabajos similares, se entiende que la experiencias sobre las cuales se desarrollaron
poseen no-linealidades de caracter debil por tratarse de sistemas amplificadores de ruido. En
contraposicion, se escoge como fenomeno fsico a controlar un sistema de oscilaciones auto-
sostenido, que presenta marcadas no-linealidades.
A su vez, se estudia una metodologa de sensado que relaje las condiciones necesarias para
poder realizar la experiencia fuera de laboratorios. En tal sentido, se opta por plantear un
controlador basado en la medicion de propiedades sobre imagenes de la experiencia suponiendo
la inyeccion de humo u otro trazador pasivo aguas arriba.
Como sistema fsico bajo control se selecciona el escurrimiento de un cilindro inmerso en
un flujo uniforme con el objetivo de controlar su estela. El forzado del flujo es producido por
actuadores de plasma colocados en la superficie del cilindro. A fines practicos, se utilizan veloci-
dades del fluido tales que la estela presente desprendimiento de vortices y un caracter netamente
laminar como se vera en los siguientes captulos.
Se utiliza un modelo ARX para expresar la dinamica de la estela del cilindro a traves de
un vector de estado cuyas coordenadas son la intensidad del escalar pasivo observado en ciertos
puntos de la imagen y la intensidad de actuacion. El controlador elegido posee un esquema
GPC para minimizar las fluctuaciones de la estela dentro de un horizonte de prediccion. Como
paso de verificacion previo a la implementacion real de la experiencia, se simula numericamente
el fenomeno, garantizando la ausencia de interferencias con senales externas y otras formas
de ruido. Los resultados del controlador son integrados dentro del codigo de simulacion para
sincronizar el momento de actuacion con los pasos de la simulacion propiamente dicha.

34
2.6 Conclusiones

Durante el presente captulo se introdujeron los conceptos fundamentales necesarios para el


trabajo en sistemas de control de fluidos. Se realizo una breve resena sobre el desarrollo historico
de la Teora de Control y el Control de Fluidos con el fin de entender el camino transitado hasta
alcanzar los niveles de complejidad actuales.
Se clasificaron las distintas estrategias de control en cuanto a bucles de control y actuadores
utilizados ejemplificando en cada caso con distintas experiencias del area del control de fluidos.
En ese escenario se remarco la importancia de los actuadores reactivos y en especial de lazo
cerrado (o feedback ) debido a su flexibilidad frente a cambios en las condiciones del sistema. A
su vez, se detallaron las distintas estrategias de modelizacion para fenomenos de fluidodinamica
focalizando en las de caja negra. En ese tipo de modelos resulta indispensable la identificacion
de sistemas en base a fases de entrenamiento.
Por ultimo, se expuso la problematica a tratar, siendo fundamental la participacion de un
equipo interdisciplinario. En ese contexto se detallaron los avances conocidos a la fecha y la
importancia de obtener un control a lazo cerrado, lineal y basado en imagenes. A tal fin, se
establecio la experiencia de control sobre la estela de un cilindro como caso prototipo y se
definieron los detalles generales del experimento numerico.

35
Parte 3

Solucion y Diseno de la Experiencia

36
3.1 Introduccion

En este captulo son presentados los conceptos basicos sobre la experiencia del escurrimiento
sobre un cilindro en 2D, elegida como experimento prototipo para comprobar el algoritmo de
control. Se introduce una caracterizacion basica sobre las zonas del flujo alrededor del cilindro y
el fenomeno de desprendimiento de vortices en su estela. Asimismo, se ejemplifican algunos de
los mecanismos de actuacion mas utilizados para reducir la turbulencia y desprendimiento de
vortices en el cilindro, a saber: actuacion por rotacion e inyeccion de plasma. Luego de lograr
el entendimiento necesario sobre la fsica del sistema, se analizan brevemente ciertos casos de
aplicacion de control para esta experiencia, haciendo hincapie en los cuerpos romos (o bluff
bodies).
Luego, se define la estructura del sistema en estudio indicando dimensiones y condiciones de
simetra que seran utilizadas en la simulacion pertinente. En este contexto se establece la posicion
de los inyectores de humo, los actuadores de plasma y los sensores visuales sobre la estela del
cilindro. Conociendo las caractersticas de actuacion y sensado previstas para la experiencia,
se definen las variables de entrada y salida que regiran el problema junto con el algoritmo de
identificacion del sistema ARX que las vincula en un modelo matematico.
Por ultimo, se define el algoritmo de control a implementar utilizando un controlador predic-
tivo del tipo GPC. Se establece la funcion objetivo y se resume la importancia de las variables
de ajuste de la experiencia, tambien conocidas como parametros de tuning.

37
3.2 Sistema Fsico Bajo Estudio

El flujo viscoso externo alrededor de un cilindro representa un flujo prototipo de gran interes
para la fluidodinamica. Buena parte de los estudios de flujos en estelas de bluff bodies (ver seccion
3.2.3) han sido realizados sobre cilindros, gracias a su simple geometra y el comportamiento
caracterstico del flujo de separacion de la capa lmite.

3.2.1. Estela de un Cilindro


Se distinguen distintas regiones del flujo sobre el cilindro donde se originan fenomenos aso-
ciados con la perturbacion (Fig. 3.2.1). Se estudiara unicamente su estela, donde el fenomeno de
desprendimiento de vortices y la turbulencia asociada tienen un caracter oscilatorio marcado.

Figura 3.2.1: Regiones del flujo perturbado. Se pueden identificar distintas regiones: (i) flujo retardado, (ii) capas
lmite formadas en la superficie del cilindro, (iii) capas de corte, regiones de flujo separado y acelerado, (iv) estela
del cilindro.(Zdravkovich (1997) [70].

UD
En base a las dimensiones del problema se define al numero de Reynolds, Re = . Siendo

U la velocidad del flujo incidente, D el diametro del cilindro y la viscosidad cinematica. Este
numero es de suma importancia en experiencias que poseen movimiento relativos de fluidos
respecto a superficies ya que permite la clasificacion y comparacion de resultados. En efecto,
ciertas caractersticas en la dinamica de las experiencias son dependientes del Re utilizado y
pueden ser comparadas con otras configuraciones de Re similares aunque las escalas sean muy
diferentes.

3.2.1.1. Desprendimiento de Vortices


El fenomeno de desprendimiento de vortices resulta principalmente de la desaceleracion del
fluido mas cercano a la superficie del cuerpo y su imposibilidad de mantener la velocidad poten-
cial del flujo mas alejado (Fig. 3.2.2). Dependiendo del Re de la experiencia, es posible observar

38
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

el desprendimiento regular de vortices con signos opuestos, de una y otra parte del cilindro.
Las sucesivas posiciones que ocupan los vortices son conocidas como camino de von Karman.
fD
Se puede definir un numero adimensional llamado numero de Strouhal: St = , donde U es
U
la velocidad del flujo, f es la frecuencia de desprendimiento de vortices y D es el diametro del
cilindro. En la Fig. 3.2.2 se puede observar un camino de von Karman tpico durante experiencias
de laboratorio mientras que la Fig. 3.2.3 muestra la generacion de oscilaciones que comienzan
luego de la region de recirculacion que desestabilizan al flujo.

Figura 3.2.2: Mecanismo de separacion de la capa lmite y camino de von Karman. Izq.: Perfil de un cilindro, lneas
potenciales del flujo y distribucion de presiones del flujo ideal. Se puede observar la aceleracion del flujo entre D y
E junto con su desaceleracion entre E y F producto de los cambios de presion. En el flujo real, la friccion viscosa
contra la pared del cilindro se suma a la desaceleracion provocando una insuficiencia para seguir la trajectoria
potencial con la consecuente separacion en el punto S (Schlichting, 1978) [59]. Der.: Desprendimiento de vortices
alternados formando el camino de von Karman.

Captulo 3.2. Sistema Fsico Bajo Estudio 39


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 3.2.3: Formacion de los vortices von Karman. En primer termino, la estela del cilindro presenta burbujas
de recirculacion que se desprenden dando lugar a la generacion de vortices alternados (Perry.1982) [50].
Captulo 3.2. Sistema Fsico Bajo Estudio 40
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

3.2.1.2. Regmenes de Escurrimiento


Los distintos regmenes que pueden tener lugar en el flujo alrededor de un cilindro se clasifican
en funcion del numero de Reynolds [69]. A medida que este aumenta, el regimen alterna entre
los modos laminar permanente (5 < Re < 49), desprendimiento laminar de vortices (49 < Re <
200), transicion de las capas de corte (200 < Re < 3 105 ), desprendimientos asimetricos y
simetricos (3 105 < Re). La transicion entre los distintos regmenes no es abrupta y los efectos
de las regiones vecinas pueden estar presentes si se utilizan rangos cercanos.
Como se vera en la seccion 3.3, el presente estudio se centra en valores de 219 < Re < 282
y por lo tanto en la transicion de las capas de corte. Este regimen se caracteriza por tener
una estela del flujo turbulenta aunque en la zona de separacion se mantiene el flujo laminar.
Aun fuera de la region de desprendimiento laminar de vortices, se mantienen sus caractersticas
variando gradualmente hacia una estela completamente turbulenta a medida que aumenta Re.
Como agregado, en las capas de corte comienzan a desarrollarse estructuras tridimencionales
(3D) como consecuencia de la complejidad del escurrimiento. Sin embargo, se decide estudiar
los efectos 2D del fenomeno ya que esta demostrado que frente a la actuacion sincronizada sobre
el cilindro se mantienen las caractersticas regulares bidimensionales (2D) del fenomeno hasta
valores Re 450 [19].

3.2.2. Actuacion sobre el Cilindro


Existen una gran cantidad de estudios de control activo sobre el cilindro con el objetivo de
estabilizar su estela. A continuacion se describe el modelo de actuacion mas usual que consiste
en forzar la rotacion del cilindro. En contraposicion, se presenta el esquema de actuacion por
inyeccion de plasma, de gran aceptacion en los ultimos anos debido a ciertas ventajas experi-
mentales.

3.2.2.1. Actuadores por Rotacion


Se trata de uno de los mecanismos de control de cilindros mas estudiados. Consiste en
forzar la rotacion del cilindro sobre su propio eje. Esta rotacion puede ser completa o a modo de
oscilaciones temporales siendo este esquema el mas utilizado. Los movimientos rotatorios pueden
variar en frecuencia o en amplitud provocando distintos efectos sobre la estela resultante. El
mecanismo de rotacion oscilatoria provoca un retardo temporal en la separacion que disminuye
el efecto de arrastre [60].
En [66] se estudia el retardo en la aparicion de vortices bajo un sistema de control oscilatorio
concluyendo que las oscilaciones forzadas participan en la generacion de vortices adicionales
que interactuan con los naturales. Esta contribucion puede resultar constructiva o destructiva
a la generacion global de vortices dependiendo de la diferencia de fase entre las oscilaciones y
el desprendimiento natural del sistema. Se demuestra entonces que el efecto de las oscilaciones
puede amplificar o reducir las fluctuaciones en la estela del cilindro dependiendo de la frecuencia
y amplitud de oscilacion. La Fig. 3.2.4 y 3.2.5 dan ejemplo del efecto estabilizador con la eleccion
adecuada de parametros.

Captulo 3.2. Sistema Fsico Bajo Estudio 41


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 3.2.4: Control por Rotacion Oscilatoria. La frecuencia de actuacion fue fijada mientras que la amplitud de
rotacion (A = Vtangencial /Vf lujo ) se definio en A = 1 y A = 2 respectivamente (Thiria, 2006) [66].

Figura 3.2.5: Control por Rotacion Oscilatoria. Continuando con la secuencia anterior, la amplitud de rotacion se
aumenta llegando a A = 4 y A = 5 respectivamente [66]. Se puede observar la cancelacion de desprendimientos
de vortices en la estela cercana para oscilaciones de amplitud suficientemente alta (Thiria, 2006).

3.2.2.2. Actuadores de Plasma


Dentro de las tecnicas de actuacion activas para el control de flujos se puede clasificar a
la actuacion por plasma (medio gaseoso ionizado) fros como sistema emergente y en plena
expansion [56, 52, 62]. El mecanismo fundamental de estos actuadores consiste en forzar la
migracion de cargas mediante la disposicion de electrodos que provocan la ionizacion del gas
circundante. La inyeccion de cantidad de movimiento junto a las paredes del cuerpo bajo estudio
puede ser utilizada para reducir el arrastre por friccion de la superficie y retardar la separacion
de la capa lmite.
En la Fig. 3.2.6 se puede observar una posible configuracion de actuadores de plasma sobre
un cilindro. Las Fig. 3.2.7 muestra la misma configuracion de actuadores en funcionamiento
sobre una experiencia de laboratorio y la comparacion con el escenario no actuado [40].

Captulo 3.2. Sistema Fsico Bajo Estudio 42


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 3.2.6: Dispositivo de actuacion por plasma montado en un cilindro (1) para estabilizar su estela. Se pueden
observar 4 electrodos externos (2) cada uno con su par interno (3). El cilindro posee una proteccion interna para
evitar descargas (4). El esquema muestra tambien la zona de descarga de plasma sobre las paredes del cilindro
(5) (Kozlov, 2010) [40].

Como principales virtudes de esta tecnica se puede mencionar el escaso volumen y peso,
la simpleza del montaje y la ausencia de partes moviles. Estas caractersticas, que resultan
cruciales en la etapa de implementacion sobre aplicaciones reales, superan las posibilidades de
la mayora de los actuadores mecanicos. Otro factor de importancia consiste en los tiempos de
respuesta cortos, del orden de 1ns para el establecimiento de la descarga gaseosa. Estos tiempos
se encuentran muy por debajo de los perodos caractersticos y tiempos de muestreo necesarios en
varios escenarios de control de fluidodinamica (ver seccion 2.4). En contraposicion, los esquemas
de actuacion que implican movimientos mecanicos poseen tiempos de respuesta mas prolongados
que les restan flexibilidad en experiencias de alta velocidad.
Se decide entonces utilizar este esquema de actuacion para la experiencia prototipo bajo
estudio. En particular, es importante destacar las bondades extras que poseen los actuadores
ElectroHidroDinamicos (EHD) [56, 62] donde las corrientes obtenidas son relativamente bajas
y no es necesaria la aplicacion de campos magneticos externos. Este tipo de actuadores son
simulados durante la experiencia y recomendados para su posterior implementacion.

Figura 3.2.7: Efecto de la actuacion por plasma en la estela de un cilindro (Kozlov, 2010) [40].

3.2.3. Aplicaciones Particulares de Control sobre el Cilindro


Se pueden identificar basicamente dos ramas de la industria donde la aplicacion de control
sobre estructuras comparables al cilindro cobra importancia: vehculos (industria del automovil,

Captulo 3.2. Sistema Fsico Bajo Estudio 43


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

aeroespacial y nautica) y balstica.


En el ambito del transporte son conocidos los grandes esfuerzos de investigacion sobre las
condiciones aerodinamicas (o hidrodinamicas) de las superficies en contacto con el fluido. Estos
casos de control pasivo, donde se plantean estructuras con poca resistencia al fluido o superfi-
cies que generan poca turbulencia en su estela, fueron indispensables para reducir el gasto de
combustible y aumentar las velocidades de los automoviles, aeronaves y navos.
Sin embargo, existen casos donde se deben ubicar ciertas estructuras por sobre el fuselaje de
la aeronave para que puedan operar correctamente (emisores y receptores de senales, camaras
de video, sensores infrarrojos, estructuras portantes, etc.). Estas superficies excedentes suelen
poseer una longitud en direccion del flujo similar a su longitud en direccion perpendicular al flujo.
Esa relacion de medidas les otorga un arrastre por friccion despreciable respecto al arrastre por
presion que ofrece su forma. Estos elementos son conocidos como cuerpos romos o bluff bodies.
A modo de ejemplo en automoviles, se puede mencionar a los espejos retrovisores que re-
sultan imprescindibles debido a su utilidad. Por otro lado, en los nuevos modelos de aviones
no tripulados (unmanned aerial vehicles o UAVs) se pueden encontrar varias estructuras cla-
ves como las camaras infrarrojas y los emisores de senales (Fig. 3.2.8) que resultan de extrema
importancia para el manejo de la aeronave.

Figura 3.2.8: Ejemplos de bluff bodies en aumoviles y UAVs. Tanto el espejo retrovisor como las estructuras de
control de los UAVs son claros ejemplos de elementos que no se pueden integrar al fuselaje debido a la naturaleza
de su uso.

En los ejemplos anteriores, la existencia de bluff bodies implica la aparicion de una estela con
desprendimiento de vortices o turbulencia que puede generar arrastre, ruido y vibraciones.
La relacion de la experiencia del cilindro en 2D con el control de proyectiles resulta evidente.
Los proyectiles son claros ejemplos de bluff bodies y el control de propiedades como el arrastre,
sustentacion o turbulencias son de suma importancia para la balstica. Si bien, este campo de es-
tudio involucra efectos 3D no despreciables, el pasaje a 2D se justifica en escenarios simplificados
o donde reducir el tiempo de computo prevalece frente a la exactitud de los resultados.

Captulo 3.2. Sistema Fsico Bajo Estudio 44


3.3 Diseno y Objetivos de la Experiencia

Se considera el flujo alrededor de un cilindro con el objetivo de estabilizar su estela redu-


ciendo el desprendimiento de vortices y la energa cinetica de las fluctuaciones. Como fuera
explicado, esta configuracion posee principal importancia por su caracter de experiencia pro-
totipo ampliamente estudiada. Respecto de intentos de control sobre la estela del cilindro, es
posible encontrar una revision sobre distintas experiencias con feedback en [13].
Se conocen casos donde, aun bajo importantes interacciones no-lineales entre los modos
globales y la entrada de control, se logra la supresion de oscilaciones en las senales de los
sensores utilizados para la experiencia [25, 57]. Si bien no existe una relacion directa entre las
oscilaciones en los sensores y la energa cinetica de las fluctuaciones del flujo en su totalidad,
se puede afirmar la posibilidad de utilizar modelos lineales para controlar ciertas cantidades de
forma local. Con estas consideraciones se puede formular el objetivo de control centrado en la
manipulacion de las variables en torno a ciertos puntos en lugar de pretender un control sobre la
dinamica total de los modos oscilatorios del sistema. Una forma de conseguir esto es observando
las lneas de emision del flujo, que se denotan mediante la acumulacion de trazador pasivo, y
restringiendo su dinamica a cierto patron en la estela del objeto.
En el caso particular del escurrimiento del cilindro, se conoce que la estabilizacion produce
una estela mas angosta y larga. Entonces, al forzar la estela a que cumpla este patron, se
espera que la energa de las fluctuaciones disminuya. Con ese fin, se disponen varios sensores
formando un tunel que demarca los lmites pretendidos para las lneas de emision aguas abajo
del cilindro.

3.3.1. Configuracion y Dimensiones


La experiencia consta de un flujo entrante uniforme, de velocidad constante, que atraviesa
un cilindro centrado respecto del eje perpendicular al flujo. El cilindro sera modelado con un
disco unitario en 2D. Se establece el centro del sistema de coordenadas cartesianas en el centro
del disco. El eje de abscisas se define del mismo sentido que el flujo entrante (Fig. 3.3.1). La si-
mulacion numerica es planteada con magnitudes adimensionales para posibilitar su escalamiento
a las dimensiones reales en el caso de implementar la experiencia en un laboratorio. La correcta
extension a un escenario real requiere entonces que se respeten las proporciones y relaciones
adimensionales prefijadas (como el numero de Reynolds).

45
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 3.3.1: Estructura y dimensiones de la experiencia. El dominio de simulacion es medido proporcional al


tamano del disco que se considera unitario. Se fijan los lmites de la simulacion en 27.5 x 25 diametros con el disco
centrado verticalmente a 7.5 diametros de la entrada del flujo.

La velocidad constante de entrada se define como unitaria y se deja variable al flujo de


salida para que fluctue dependiendo de los resultados de simulacion de las celdas mas cercanas.
La presion de referencia se decide colocar en el borde de salida y con valor nulo. Respecto de
las condiciones de borde restantes, los laterales plantean simetra mediante la variacion nula
de presion y velocidad respecto de la componente normal a los mismos. De forma analoga,
la condicion de flujo entrante (inlet) posee variacion nula de la velocidad y presion respecto
de la normal. Por otro lado, la condicion de flujo saliente (outlet) define como nula solo a la
variacion de la velocidad normal. Cabe aclarar que al aplicar una variacion nula respecto de
la normal a cierto borde, se pretende modelar una extension infinita de la superficie en dicha
direccion. En el caso del flujo saliente, una variacion nula de la velocidad permite repetir el valor
simulado para las celdas interiores en las celdas exteriores (fuera de los lmites de la simulacion).
Las condiciones de borde donde se fija el valor de la magnitud, como en el caso del inlet son
conocidas como Condiciones de Dirchlet. Por otro lado, cuando se fija el valor de la variacion (es
decir, del gradiente), como el caso del outlet, se trata de una Condicion de Neumann. El detalle
de las condiciones de borde y las dimensiones del problema son indicadas en la Fig. 3.3.2.

Captulo 3.3. Diseno y Objetivos de la Experiencia 46


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 3.3.2: Condiciones de borde, disposicion de sensores y actuadores de la experiencia. Se pueden observar
las condiciones de borde en los distintos laterales de la experiencia. Los actuadores son dispuestos sobre la pared
del disco y los sensores se alinean aguas abajo.

El numero de Reynolds elegido para la experiencia es Re = 235. Dado que la velocidad del
flujo fue definida al igual que el diametro del cilindro, se fija el Re ajustando la viscosidad del
fluido a = 2351 , segun:
UD 1
= =
Re 235
= 2351 4,2553E 3

Luego de establecer los parametros generales de la experiencia, es posible estimar la frecuencia


de desprendimiento de vortices mediante una aproximacion del numero de Strouhal. Se conoce la
relacion entre Re y St mediante la tabulacion de distintas experiencias y la elaboracion de curvas
3.3.3. Esta relacion presenta discontinuidades marcadas y, por lo tanto, no puede encontrarse
una forma funcional que la sintetice a menos que se la defina por tramos. Sin embargo, en
regiones de trabajo acotadas es posible aproximar el numero de Strouhal mediante una funcion
del Re. Para el Re elegido, se puede aproximar un valor de St = 0,1814 gracias a la relacion
matematica que resulta valida en entornos de Re 250:
   
19,7 19,7
St = 0,198 1 = 0,198 1
Re 235
0,1814

Captulo 3.3. Diseno y Objetivos de la Experiencia 47


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 3.3.3: Evolucion del numero de Strouhal en funcion del numero de Reynolds (Williamson, 1996) [69].

3.3.2. Sensores y Actuadores


Un filamento de trazador pasivo de concentracion unitaria es inyectado en la entrada del
fluido. Este trazador modela la inyeccion de humo que difunde a traves del escurrimiento permi-
tiendo el sensado de su concentracion en la estela del cilindro. A fines practicos de la simulacion,
se colocaran puntas de medicion (o probes) dentro de la aplicacion de simulacion para obtener la
concentracion en ciertos puntos. En un escenario real, se pueden sensar estos valores mediante
la captura de imagenes en escala de grises y la comparacion de las intensidades en dichos puntos
con la del punto de inyeccion (concentracion patron unitaria).
Se dispone de 2 lneas de sensores, simetricas respecto del eje X de la simulacion, con 4
sensores cada una para capturar los valores de concentracion del escalar difundido aguas abajo
del cilindro (Fig. 3.3.2). Las posiciones elegidas para los sensores pretenden demarcar un tunel
a traves del cual se debe canalizar el escalar inyectado en un caso de control optimo. En el caso
no estabilizado, los sensores captaran el desplazamiento de los vortices y las fluctuaciones de
velocidad por la turbulencia de la estela. Es importante remarcar que la eleccion de la posicion
de cada sensor y la cantidad de sensores utilizados resulta del ajuste luego de ejecutar varias
experiencias de control. El algoritmo y parametros de configuracion propuestos en las siguientes
secciones demostraron ser altamente sensibles a la configuracion de la experiencia. De todas
formas, se destaca que el concepto de tunel y sensado por vision propuestos resultan genericos
y adaptables a una gran variedad de experiencias.
Se definen entonces las variables yi (k) con i = 1.,8 para el valor medido en cada sensor en
el paso de tiempo k suponiendo un muestreo discreto. Dado que el trazador introducido posee
concentracion unitaria en el punto de inyeccion, se espera que las variables yi posean valores
entre 0 y 1. Asimismo, se define el vector generico y(k) = (y1 (k) . . . ym (k))T Rm con m = 8

Captulo 3.3. Diseno y Objetivos de la Experiencia 48


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

que sera de utilidad para operar con las mediciones del paso k de forma matricial.

Se agregan 2 actuadores simetricos en la superficie del cilindro. Los actuadores poseen una
longitud de aproximadamente un 5 % de la circunferencia del cilindro y modelan los dispositivos
de inyeccion de plasma. La funcion de los actuadores es la adicion sincronizada de cantidad de
movimiento tangencial a la superficie del cilindro. Los actuadores son dispuestos cerca del punto
de separacion (Fig. 3.2.2) con el objeto de retardar la separacion de la capa lmite respecto de
la superficie del cilindro mediante la inyeccion simetrica de plasma. Estudios previos bajo una
configuracion similar demostraron que la inyeccion constante con una amplitud suficientemente
alta permite estabilizar la estela del cilindro [18]. En este caso, se propone estabilizar la estela
mediante una actuacion variable durante el tiempo, que acepte las fluctuaciones naturales del
modelo fsico, y que eventualmente requiera una amplitud menor.
El actuador es simulado como en [18] y [28] mediante una condicion de borde en una region
localizada del cilindro. La amplitud de la actuacion indica la magnitud de velocidad tangencial
inyectada por los actuadores. Se define entonces la variable u(k) como la magnitud de la velocidad
tangencial inyectada por ambos actuadores de forma simultanea en el paso de tiempo k. De forma
analoga a la definicion de y(k), se considera una forma mas general de la variable de actuacion
segun u(k) Rr con r = 1.
A menos que se especifique lo contrario, se considera una inyeccion ideal del trazador y
mediciones perfectas en los sensores. Asimismo, se asume una velocidad de entrada constante,
uniforme a lo largo del eje de las ordenadas y constante en el tiempo. Esta situacion dista
de cualquier escenario de experimentacion real donde existen fluctuaciones en los sistemas de
inyeccion y errores inherentes al esquema de camaras e iluminacion utilizados. Esto permite
centrar la atencion en las senales puras provenientes de la dinamica del fenomeno y demorar el
analisis de ruido u otro tipo de perturbaciones. Los efectos de las perturbaciones seran tomados
en cuenta en una etapa posterior a la verificacion de la efectividad del algoritmo a lazo cerrado.
En esa etapa se pondra a prueba la robustez del sistema frente a la existencia de ruido en la
inyeccion del escalar, en las condiciones de entrada y en las mediciones de los sensores.

3.3.3. Sntesis y Objetivos de la Experiencia


A modo de sntesis se resumen los parametros importantes del sistema fsico a simular. En
cada caso se incluye su valor y una resena de la variable utilizada, en caso de existir (Tabla
3.3.1):

Propiedad Variable Valor (adimensional)


Reynolds Re 235
Strouhal estimado St 0,1814
Diametro Cilindro D 1
Viscosidad Fluido 2351
Vel. Flujo Entrada U 1 Cte. (Cond. Dirichlet)
Vel. Flujo Salida Gradiente Nulo (Cond. Neumann)
Entradas y(k) Concent. de Escalar en el tiempo k
Salidas u(k) Amplitud de actuacion en el tiempo k

Tabla 3.3.1: Sntesis de variables utilizadas en la experiencia de simulacion.

En las siguientes secciones se define el algoritmo de identificacion del sistema, planteando


como vector de estado del sistema al conjunto de las variables y(k) y u(k) para cada paso de

Captulo 3.3. Diseno y Objetivos de la Experiencia 49


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

tiempo. El sistema identificado permite predecir los estados futuros de las salidas si se asumen
ciertas entradas.
Luego se considera el algoritmo de control que calcula el valor adecuado de u(k) para los yi (k)
medidos en el paso k y anteriores. El valor de actuacion calculado buscara cumplir el objetivo
de control que consiste en disminuir la concentracion medida en el conjunto de sensores para
forzar un fenomeno de tunel del humo sobre el camino formado por los sensores. Este objetivo
puede ser planteado gracias a la disposicion de los elementos en la experiencia y su caracter de
simetra respecto del tunel.

El sistema fsico elegido como escenario de verificacion plantea dificultades importantes en


el terreno de la identificacion del sistema y la definicion del controlador. Se trata de un sistema
con oscilaciones auto-sostenidas que posee un caracter no-lineal marcado. Esta caracterstica
es reforzada por el numero de Reynolds elegido dentro de una zona de transicion, en la cual
se presentan fenomenos mixtos de desprendimiento laminar de vortices y turbulencia. En ese
contexto, se espera que las no-linealidades sean aun mas notorias.
Por otro lado, el esquema de sensado y control elegidos plantean ciertas ventajas sobre otros
trabajos de control para escenarios similares. En primer lugar, el empleo de trazadores pasivos
como elemento de medicion en lugar de otras variables fsicas (presion, campo de velocidades,
etc) desva el foco de la dinamica instantanea a una medida mas general del sistema, donde
las no-linealidades no resultan tan evidentes. En segundo lugar, se relaja el objetivo de control
al proponer el desvo de los trazadores dentro de un tunel que se conoce como una solucion
factible para el problema en estudio. Esto acota los grados de libertad de la experiencia dentro
de ciertos lmites que admiten una solucion de control conocida.
Por ultimo, es importante recalcar que aunque se demuestra la efectividad del algoritmo de
control en el caso de 8 variables de salida simultaneas y 1 variable de entrada, su definicion es
generica y como consecuencia se lo puede clasificar como un sistema de control MIMO.

Captulo 3.3. Diseno y Objetivos de la Experiencia 50


3.4 Algoritmo de Identificacion del Sistema

Para representar la dinamica del flujo se considera un sistema lineal invariante en el tiempo
definido segun:
y(k) + 1 y(k 1) + + na y(k na ) =
1 u(k) + 2 u(k 1) + + nb u(k (nb 1))
donde y(k) Rm representa el estado observable del sistema (la salida), u(k) Rr representa
la actuacion (la entrada) y k N es el paso de tiempo actual. Los vectores y(k) y u(k) poseen
las m componentes de salida y las r componentes de entrada que se consideran observables para
cada paso de tiempo k dentro de la experiencia. Las variables na N y nb N definen los
horizontes de auto-regresion para y y u respectivamente. A modo de simplificacion se puede
asumir na = p y na = nb 1 sin perder generalidad. Reformulando los coeficientes del termino
derecho se obtiene una nueva forma del sistema:
y(k) + 1 y(k 1) + + na y(k na ) =
(3.4.1)
0 u(k) + 1 u(k 1) + + p u(k p)
donde p N define el orden del modelo.
Nos referimos al sistema como un modelo AutoRegressive with eXtra inputs(ARX). Los coe-
ficientes i para 1 i p y i para 0 i p, de tamanos m m y m r respectivamente, son
llamados observer Markov parameters y caracterizan el modelo [33].
Si se define el vector de parametros

:= (1 . . . p 0 . . . p )T R(pm+(p+1)r)m

y el vector de regresion

y(k 1)
..

.

y(k p)
(k) =
Rpm+(p+1)r (3.4.2)
u(k)

..
.
u(k p)
la Eq. 3.4.1 puede ser escrita de la siguiente forma

y(k) = T (k).

Por otro lado, definiendo , un vector de tamano d := pm2 + (p + 1)mr que contiene todos
los coeficientes de las matrices i y i , y considerando (k) := (k) Im , siendo el producto
de Kronecker e Im la matriz identidad m m, es posible reescribir la Eq. 3.4.1 de la siguiente
forma
y(k) = T (k).

51
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Para estimar , se define una fase de entrenamiento donde se fuerza al actuador mientras
se mide la respuesta del sistema fsico durante N pasos de tiempo. Se propone como senal de
actuacion para el entrenamiento un pulso de gran amplitud y corta duracion, que permita captar
la respuesta del sistema a un gran rango de frecuencias. La Fig. 3.4.1 presenta un diagrama de
bloques que sintetiza la fase de entrenamiento e identificacion del sistema.

Figura 3.4.1: Esquema de bloques de la fase de identificacion del sistema.

Las N muestras del entrenamiento son utilizadas bajo el criterio de estimacion de mnimos
cuadrados para obtener un estimador N LS de . Se evalua (k) sobre el conjunto de las N

muestras de entrenamiento utilizando p + 1 k N . Se asume el inicio del muestreo en k = 1


teniendo disponibles los valores de y(1), . . . , y(N ), u(1) . . . , u(N ):
1
N N
LS 1 X 1 X
N = (k)T (k) (k)y(k). (3.4.3)
N p N p
k=p+1 k=p+1

Dado que la matriz N T


P
k=p+1 (k) (k) puede resultar mal condicionada, es decir que esta cer-
ca de ser no inversible debido a su valor o a la precision numerica, se considera un metodo mas
efectivo para estimar los parametros [42]. Se define entonces

T := ((p + 1) . . . (N )) Rd(N p)m ,


YT := (y T (p + 1) . . . y T (N )) R1(N p)m .

Finalmente, la estimacion de se obtiene de una descomposicion QR de la matriz [Y ]


R(N p)m(d+1) en la cual las primeras d columnas corresponden a las columnas de y la ultima
columna es el vector Y .
Con estas definiciones, el problema consiste en obtener un que minimice kY k2 . Se
considera una descomposicion QR dada por [Y ] = QR, con Q ortonormal de (N p)m (N
p)m y R triangular superior de (N p)m (d + 1) tal que

R1 R2
R = 0 R3
0 0

siendo R1 una matriz d d triangular superior, R2 un vector d 1 y R3 un escalar. Es posible


demostrar que la minimizacion de kY k2 es equivalente a minimizar kQT (Y )k2 . Como
QT corresponde a las primeras d columnas de R y QT Y a la ultima columna de R, se obtiene
que
  R2
R1
QT = , QT Y = R3
0
0

Captulo 3.4. Algoritmo de Identificacion del Sistema 52


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

 
R2 R1
Entonces, se concluye que kQT (Y )k2
=k k2 . Al determinar esta cantidad y
R3
resolver el sistema R1 = R2 se despeja , el estimador de , segun:

= R11 R2 (3.4.4)

Este sistema suele estar mejor condicionado que Ec. 3.4.3 y por lo tanto es menos sensible a
ruidos, diferencias de magnitudes medidas, similitud de mediciones en distintos sensores, etc.

Parametros Utilizados
Como parametros destacados de la estrategia de identificacion del sistema se pueden men-
cionar a la duracion y amplitud del pulso forzado como actuacion, el numero de muestras del
perodo de entrenamiento N y el horizonte de autoregresion determinado por p. Si bien es posible
ajustar dichos parametros considerando unicamente el grado de aproximacion del modelo ARX
respecto de las muestras observadas y la posibilidad de predecir estados futuros, se observo que
tales ajustes no aseguraban necesariamente un buen control. Dado que la estrategia de identi-
ficacion del sistema se encuentra integrada con el algoritmo de control, se decide posponer la
seleccion de parametros hasta definir el controlador y poder verificar que los ajustes aseguran
los objetivos de control propuestos. La Tabla 3.4.1 incluye una lista detallada de las propiedades
y variables utilizadas en esta fase.

Propiedad Variable
Cant. variables de salida m
Cant. variables de entrada r
Orden del sistema p
Cant. muestras de entrenamiento N
Actuacion de entrenamiento u(1) . . . u(N )

Tabla 3.4.1: Sntesis de variables utilizadas en la identificacion del sistema.

Captulo 3.4. Algoritmo de Identificacion del Sistema 53


3.5 Algoritmo de Control a Lazo Cerrado

Luego de la identificacion del model ARX, es necesario establecer el lazo cerrado del control
y definir el algoritmo de feedback apropiado. La Fig. 3.5.1 muestra un diagrama de bloques de
la fase de control que se considera a continuacion.

Figura 3.5.1: Esquema de bloques del algoritmo propuesto.

Siendo s N el horizonte de prediccion, se definen ys Rsm , us Rsr and vp Rp(m+r)


tales que
y(k) u(k)
ys (k) := .. ..
, us (k) := ,

. .
y(k + s 1) u(k + s 1)

y(k 1)
..

.

y(k p)
vp (k p) :=
u(k 1) .


..
.
u(k p)
De acuerdo con la Ec. 3.4.1 se puede obtener una expresion matricial para predecir las salidas
futuras del sistemas [33]
ys (k) = T us (k) + vp (k p) (3.5.1)
donde T es una matriz de Toeplitz definida segun

0
(1) 0
0
T := 0(2) 0
(1)
0 (3.5.2)



... ... ... ... ...
(s1) (1)
0 ... ... 0 0
(1) (s1)
y los coeficientes 0 , 0 , . . . 0 son conocidos como los parametros del sistema de Markov
(system Markov parameters) [33]. T y son matrices de mssr y msp(m+r) respectivamente
y son obtenidas por una serie de relaciones recursivas segun se describe en [33].

54
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

(k)
Los coeficientes 0 son llamados parametros de respuesta del sistema al pulso (pulse reponse
parameters y son obtenidos segun:

(0)
0 = 0
k
(k) (ki)
X
0 = k + i 0 ,1 k p
i=1
p
(k) (ki)
X
0 = i 0 ,k > p
i=1

mientras que la matriz se define tal que



1 2 ... p 1 2 ... p
(1) (1) (1) (1) (1) (1)
1 2 ... p 1 2 ... p

:= (3.5.3)

... ... ... ... ... ... ... ...


(s1) (s1) (s1) (s1)
1 ... ... p 1 ... ... p

con coeficientes calculados de forma recursiva. En primer lugar, es necesario definir los 1k :

(0)
1 = 1 ,
k
(k) (ki)
X
1 = k+1 + i 1 , 1 k p 1,
i=1
k
(k) (ki)
X
1 = i 1 , k > p,
i=1

Luego, se calculan los kj :


(j) (j1) (j1)
1 = 1 1 + 2 ,
(j) (j1) (j1)
2 = 1 2 + 3 ,
..
.,
(j) (j1)
p1 = 1 p1 + p(j1) ,
(j1)
p(j) = 1 p ,

Y finalmente kj :
(j) (j1) (j1)
1 = 1 1 + 2 ,
(j) (j1) (j1)
2 = 1 2 + 3 ,
..
.,
(j) (j1)
p1 = 1 p1 + p(j1) ,
(j1)
p(j) = 1 p .

El algoritmo de control se basa en un esquema Generalized Predictive Controller (GPC)[14,


15, 35] cuya funcion objetivo consiste en reducir la concentracion de escalar medida en los

Captulo 3.5. Algoritmo de Control a Lazo Cerrado 55


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

sensores. De esta forma, se pretende generar un efecto de tunel sobre el trazador pasivo que
garantice la ausencia de desprendimiento de vortices en ese segmento de la estela. En efecto, si
consideramos la simetra en la posicion de los sensores y actuadores junto con la dinamica del
sistema, podemos asumir que respuesta de control natural sera aumentar la actuacion cuando
el sistema aun no se encuentre estabilizado.
A tal fin, se define la funcion objetivo segun

J = ysT (k)Qys (k) + uTs (k)us (k) (3.5.4)

donde Q es una matriz diagonal de sm sm con bloques Qi tales que

Qi := diag(q1 . . . qm ),

y qi representa el peso del sensor i. Si bien el peso de cada sensor puede definirse como
unitario, es posible variar el valor para dar preponderancia a determinados sensores frente a
otros. De esta forma se puede tomar en cuenta la distancia de cada sensor respecto del punto
de actuacion y, por ejemplo, contemplar un peso menor en sensores con mayor retardo.
El parametro de la Ec. 3.5.4 penaliza la actuacion dentro del funcional. De esta forma se
le asocia un costo a la energa utilizada en el actuador para que el controlador se auto-regule y
consiga un balance de eficiencia. Durante la experiencia, se pudo comprobar que el valor de
considerado resulto muy sensible a la cantidad de los sensores utilizados, a su posicion y a las
escalas de los valores medidos o de actuacion. Por este motivo, se consideran experiencias de
verificacion de robustez, fuera del entorno de diseno, que mantengan fijos parametros como las
posiciones y cantidad de sensores. De la misma forma, se considera la normalizacion y cambio de
escala de los valores medidos para contar con series de datos homogeneas que quiten sensibilidad
a la variable . Estas cuestiones seran tratadas en el Captulo 4.
Es importante remarcar que la minimizacion de la funcion de costo, J, no implica de forma
directa la minimizacion de la energa cinetica de la turbulencia. Este objetivo general se alcanza
gracias a disponer adecuadamente de los sensores y a penalizar la existencia de lneas del flujo
no deseadas. De esta forma se fuerza al flujo a adoptar una configuracion particular conocida
como estable.
Se asume una ley de control lineal y se define us (k) = Kvp , donde K es una matriz de
sr p(m + r) que contiene los coeficientes del controlador.
Teniendo esto en cuenta y aplicando el metodo de Lagrange para minimizar J bajo las
restricciones dadas por la Ec. 3.5.1, se plantea el Lagrangiano L = J+ < l, ys T us vp >;
donde l Rsm simboliza el multiplicador de Lagrange y < , > es un producto interno usual
en Rsm . Buscando la solucion optima del sistema, se obtienen las siguientes ecuaciones:

ys T us vp = 0,
2Qys + l = 0,
2us T T l = 0.

De ellas se determina que

K = (T T QT + Isr )1 T T Q (3.5.5)

donde Isr representa la matriz identidad de sr sr, y entonces

us (k) = (T T QT + Isr )1 T T Qvp (k p) (3.5.6)

Captulo 3.5. Algoritmo de Control a Lazo Cerrado 56


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Como se requiere unicamente el valor de la actuacion para el paso actual (k), es posible
ahorrar tiempo de procesamiento si se calculan solo las primeras r filas del producto en el
primer termino de la Ec. 3.5.6 segun

u(k) = {(T T QT + Isr )1 }r T T Qvp (k p). (3.5.7)

Luego de la aplicacion de la actuacion u(k) es necesario medir el estado de los sensores y(k),
calcular vp y cerrar el ciclo de control repitiendo la Ec. 3.5.7 para el nuevo paso de tiempo. A
continuacion, se resume el algoritmo de control aplicado mediante pseudo-codigo:

Algorithm 1 Algoritmo de control propuesto.


Require: p: orden del modelo, s: horizonte de prediccion, : costo del actuador
Ensure: Sistema de control bajo estudio
1: Medir los valores de la fase de entrenamiento
2: Calcular el modelo ARX de orden p
3: Definir el controlador con s, y el modelo ARX
4: Definir el vp inicial con los valores de y y u hasta el paso k 1
5: for all paso de tiempo k do
6: Usar Ec. 3.5.7 para obtener u(k)
7: Aplicar la actuacion u(k) calculada
8: Medir y(k), la salida resultante para el paso de tiempo k
9: Actualizar vp con y(k) y u(k)
10: end for

Parametros Utilizados
El parametro de mayor importancia durante la fase de control es el costo del actuador
utilizado en la funcion objetivo. Su valor debe ser restrictivo para evitar que la salida sea
controlada con un uso de actuacion poco eficiente y a su vez lo suficientemente permisivo para
que el actuador fluctue de acuerdo con la naturaleza del sistema.
La Tabla 3.5.1 resume las propiedades y variables utilizadas en esta fase.

Propiedad Variable
Horizonte de prediccion s
Costo del actuador
Pesos de cada sensor Q

Tabla 3.5.1: Sntesis de las variables utilizadas en el control a lazo cerrado.

Captulo 3.5. Algoritmo de Control a Lazo Cerrado 57


3.6 Conclusiones

El presente captulo introdujo la experiencia del escurrimiento sobre un cilindro en 2D as co-


mo los conceptos basicos asociados sobre su control. Se sintetizaron las zonas caractersticas del
escurrimiento poniendo foco en la estela del cilindro y los fenomenos de desprendimiento de
vortices y turbulencia. Asimismo, se introdujo el numero de Reynolds (Re) que caracteriza la
dinamica del fluido y el numero de Strouhal (St) que se relaciona con la frecuencia de despren-
dimiento de vortices y puede ser estimado en ciertos rangos de Re.
Luego de resumir las aplicaciones de control de bluff bodies y su relacion con la experiencia
del cilindro, se detallo el esquema experimental incluyendo las dimensiones del problema, el valor
de Re = 235 y una estimacion de Stestimado = 0,1814. Estos parametros permiten pronosticar el
comportamiento del fenomeno fsico previo a su simulacion.
Entonces, se introduce el algoritmo de identificacion del sistema que permite obtener un
modelo matematico ARX de orden p a partir de un conjunto de muestras de entrenamiento.
Asimismo se utiliza el modelo ARX calculado, p, un horizonte de prediccion s, el peso de cada
sensor y el coeficiente de penalizacion de la actuacion para definir el algoritmo de control.
Dicho sistema hace uso de tecnicas predictivas utilizando un controlador del tipo GCP. Ambos
algoritmos son definidos de manera generica, para un conjunto de m sensores y r actuado-
res arbitrarios consiguiendo un esquema de controlador MIMO lineal que puede ser extendido
facilmente a otras experiencias.

58
Parte 4

Ensayo Experimental

59
4.1 Introduccion

El presente captulo establece el mallado a utilizar durante la experiencia numerica, inclu-


yendo tipos y tamanos de celda junto con la relacion que poseen con el paso de tiempo de la
simulacion. Luego de definir la configuracion fsica y numerica de la simulacion, se obtienen los
primeros resultados que son contrastados con las predicciones realizadas sobre el fenomeno fsico
bajo estudio.
Ya verificada la validez del mallado y configuracion de la simulacion, se implementa un
esquema de comunicacion con Code Saturne que permite obtener la informacion de cada paso
de tiempo y generar una respuesta de actuacion acorde. Este mecanismo es puesto a prueba
durante una fase de entrenamiento del sistema donde se fuerza un pulso de actuacion y se
recolecta la respuesta en los distintos sensores. Las mediciones son luego relacionadas con un
modelo ARX identificado mediante el algoritmo de mnimos cuadrados propuesto en el Captulo
3.4. El modelo identificado es puesto a prueba para asegurar la capacidad de prediccion futura
respecto de distintas frecuencias de actuacion.
En la fase de control, se utiliza el modelo ARX para calcular la actuacion optima frente
a cada paso de tiempo. Se desarrolla el algoritmo de control definido en el Captulo 3.5 y se
ajustan los parametros para obtener un control apropiado para la experiencia. Luego, se practica
un analisis sobre la energa cinetica y las fluctuaciones de la estela del cilindro para verificar
la bondad del controlador desarrollado. Para ello se convierte la estructura de malla irregular
utilizada para la simulacion en una grilla cartesiana que permite la manipulacion de variables
fsicas (como la concentracion del escalar o el campo de velocidades) de manera uniforme.
Finalmente, se realiza una serie de simulaciones con condiciones fuera de diseno para verificar
la robustez del sistema de control.
La implementacion de los algoritmos de identificacion y de control son realizadas en C++
y Matlab. A su vez, se realizaron pruebas de concepto de la identificacion del sistema escrito
ntegramente en CUDA C/C++ (lenguaje de GPGPU para tarjetas Nvidia) con el objetivo de
demostrar la versatilidad del esquema propuesto y la posibilidad de realizar un sistema de alta
performance para implementar la experiencia en laboratorios [37].

60
4.2 Mallado de la Experiencia

Se efectua la simulacion utilizando el aplicativo Code Saturne [23, 2], un sistema de codigo
abierto escrito en Fortran, C99 y Python que realiza Direct Numerical Simulation (DNS). Este
tipo de simulacion consiste en discretizar la experiencia con un conjunto de celdas y resolver las
ecuaciones de Navier-Stokes para cada paso de tiempo. El conjunto de celdas se denomina malla
(o mallado) y la solucion a las ecuaciones se practica sobre los puntos de union entre celdas.
Como agregado a la resolucion del flujo de un fluido, Code Saturne permite resolver modelos
fsicos de transferencia de calor y combustion de fluidos, entre otros, mediante un algoritmo de
volumenes finitos de segundo orden utilizando el metodo de Crank-Nicolson [23].

4.2.1. Tamano de Celdas


Resulta intuitivo que a menor tamano de celda, mayor es la precision de calculo de la re-
solucion DNS. Sin embargo, un elevado numero de celdas producto de un mallado fino implica
mayores capacidades de computo para cada paso de tiempo a simular. Estos aspectos deben
mantener una relacion de equilibrio, disminuyendo el tamano de celdas en las zonas donde se
requiere mayor precision y aumentandolo en aquellas donde no es necesario un alto detalle.
La geometra del sistema fue mallada en 2D utilizando el aplicativo GID para generacion de
grillas no-estructuradas [43]. Se opto por el empleo de triangulos como tipo de polgono para las
celdas (Fig. 4.2.1) ya que permiten un facil encastre entre elementos sin necesidad de grandes
deformaciones. Si bien los triangulos no son necesariamente equilateros, se puede tomar como
tamano caracterstico a la longitud de sus lados. La malla se disena de forma tal de ser fina en la
circunferencia del cilindro (Fig. 4.2.2) y aumentar en grosor con la distancia a su centro. Lejos
del cilindro, se define un tamano medio uniforme de celdas que se extiende al resto de dominio
(Fig. 4.2.3).

Figura 4.2.1: Detalle del tipo de celdas triangulares utilizadas en el mallado no-estructurado.

61
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.2.2: Mallado de la geometra del sistema cercana al cilindro. En si bien la diferencia entre el tamano del
mallado sobre el borde del cilindro y las fronteras del dominio es grande, se utilizo una transicion gradual y varios
anillos concentricos de diversos tamanos.

Figura 4.2.3: Mallado de la geometra del sistema. Se observa claramente la diferencia de densidad de celdas entre
las cercanas del cilindro y la region circundante.

Dado que el cilindro posee un diametro unitario, su circunferencia resulta . A fines practi-
cos, se pretende un nivel de discretizacion tal que el cilindro este compuesto por 100 celdas
en su superficie. Esto implica un numero aproximado de 5 celdas para describir a cada actua-
dor, sabiendo que se representan como semi-arcos de aproximadamente 5 % de la circunferencia
(Captulo 3.3). Se define entonces un tamano de celda de 0,03 en la proximidad del cilindro y
dos anillos concentricos con tamanos de celda 0,035 y 0,05 permitiendo un aumento gradual de
las dimensiones utilizadas (Fig. 4.2.2). El tamano general del resto del dominio y lmites de la
experiencia se fijo en 0,1 (Fig. 4.2.3).
Este tipo de configuracion permite economizar enormemente el tiempo de procesamiento sin
comprometer la calidad de la simulacion en las regiones crticas. Esto es posible al destinar una
pequena cantidad de celdas a tomar dimensiones pequenas (con un bajo poder de cobertura) y
una cantidad sensiblemente mayor para aquellas de mayor tamano (con mejores posibilidades
de cubrir el amplio dominio). Es posible encontrar el detalle de las dimensiones empleados en

Captulo 4.2. Mallado de la Experiencia 62


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

cada region al generar la malla en el Apendice B.1. Se incluye ademas la distribucion final de
celdas de acuerdo a su tamano.

Ya generada la malla 2D de triangulos utilizando GID, se adaptan sus nodos a un formato 3D


para ser empleado por Code Saturne. Existen varias alternativas para realizar dicha extension, en
este caso se opta por agregar una nueva dimension al conjunto de celdas mediante la proyeccion
de sus lados. Se extiende entonces cada triangulo a un pentaedro de altura 0,005 para mantener
relacion con el orden de magnitud utilizado en las celdas mas pequenas. A tal fin, se realiza
un script de Matlab que interpreta el archivo de salida de GID, extiende cada triangulo de la
malla y genera un nuevo archivo de malla con formato .msh que puede ser consumido por Code
Saturne. El codigo fuente de dicha rutina puede encontrarse en el Apendice F.1. En la Fig. 4.2.4
se puede apreciar el agregado de una dimension ficticia a la malla original en 2D generando un
pentaedro por cada triangulo existente.

Figura 4.2.4: Extension del mallado 2D a 3D. Se observa el detalle de una vista oblicua del mallado 2D (Izq.) en
comparacion con su extension a 3D (Der.) mediante la conversion de celdas triangulares a pentaedros de altura
0,005 homogenea.

4.2.2. Paso de Tiempo


Para garantizar la estabilidad de este mecanismo, la discretizacion temporal (entre pasos
de tiempo sucesivos) y espacial (al definir los lmites de cada celda) deben permitir que el
movimiento de cada partcula de fluido sea de una fraccion de la celda. De esta forma, se consigue
una propagacion suave de los distintos cambios en las magnitudes y se evitan las variaciones
bruscas que provocan errores de calculo numerico.
Si estas condiciones no se cumplen, el sistema tiende a ser inestable durante la simulacion y,
eventualmente, diverge. Esto suele ocurrir en puntos con gran intercambio de fluidos o sectores
del mallado con celdas de tamano muy dispares. En cualquiera de los casos el flujo simulado no
recorre las celdas de forma gradual y el desacople entre los valores de distintas celdas desestabiliza
las magnitudes diferenciales simuladas que no pueden converger. En el Apendice B.2 se puede
encontrar un caso de divergencia de la simulacion como consecuencia de cambios bruscos en las
dimensiones de las celdas del mallado.
Por otra parte, el estudio matematico detallado de la resolucion numerica de ecuaciones
diferenciales en derivadas parciales contempla distintos criterios de convergencia. Uno de los

Captulo 4.2. Mallado de la Experiencia 63


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

mas utilizados es la Condicion de Courant-Friedrich-Lewy (CFL), a saber:

U t
C= < Cmax
x
donde U es la magnitud de la velocidad, (t) es el paso del tiempo y (x) indica el tamano
elegido para la discretizacion espacial del problema (en nuestro caso, el tamano de las celdas).
El coeficiente C es conocido como numero de Courant y se exige que sea menor que cierta
constante Cmax que dependera de la sensibilidad numerica del algoritmo utilizado. Cmax suele
ser inferior a 1, reforzando la necesidad de que la distancia recorrida por cada partcula en un
paso de tiempo (U t) sea menor que el tamano de la celda (x). En el caso particular del
metodo de Crank-Nicolson utilizado en la resolucion numerica, la condicion CFL no es necesaria
para asegurar la estabilidad [67] por tratarse de un metodo A-Stable pero de todas formas, un
numero de Courant bajo es importante para mantener una buena precision numerica.
Se elige entonces t = 0,061 como paso de tiempo constante para todas las simulaciones de
forma arbitraria pero verificando que C 2. En efecto, para el caso extremo de x = 0,03 y
conociendo que la velocidad caracterstica de la experiencia es unitaria, se obtiene:

1 0,061
C =
0,03
= 2,0333

Captulo 4.2. Mallado de la Experiencia 64


4.3 Simulacion de la Experiencia

Ya definido el mallado, el paso de tiempo de simulacion (t = 0,061) y las condiciones de


contorno, se construye un caso de estudio en Code Saturne para obtener las primeras mediciones.

4.3.1. Configuracion
El aplicativo posee dos archivos de suma importancia que deben ser modificados para confi-
gurar correctamente el modelo:

usini1.f90 Establece los parametros fsicos y numericos del calculo. En el se define el paso
de tiempo, viscosidad del fluido, la cantidad de pasos a simular, el orden del algoritmo de
volumenes finitos, entre otras propiedades. Tambien contiene la informacion necesaria para
definir los sensores de la experiencia que, dada la naturaleza del simulador, son definidos
mediante sondas de prueba (probes) indicando la posicion cartesiana para cada una.

usclim.f90 Define las condiciones de contorno del sistema para las distintas caras de cada celda
del mallado. De esta forma se indican las condiciones de borde del sistema mediante el
mapeo de las celdas del mallado a tipos conocidos por Code Saturne.

Es importante remarcar que mientras las subrutinas de configuracion del archivo usini1.f90 son
ejecutadas una unica vez, al inicializar el motor de calculo, la configuracion de condiciones de
contorno indicadas en usclim.f90 son invocadas cada paso de tiempo y por lo tanto, pueden
ser modificadas. En ese sentido, las condiciones de contorno son dinamicas y esto permitira
dinamizar los niveles de actuacion durante la iteracion de la simulacion.
A continuacion se incluye una breve resena sobre las principales modificaciones realizadas a
cada archivo para establecer la configuracion inicial de simulacion. El detalle del codigo fuente
utilizado puede encontrarse en el Apendice F.4.

4.3.1.1. usini1.f90
En primer lugar, es necesario fijar las variables numericas definidas para la simulacion. De
esta forma se define el paso de tiempo (dtref ), la cantidad de pasos a simular (ntmabs) y el
orden de difusion para la resolucion de volumenes finitos (blencv ) tanto en las componentes
de velocidad (iu, iv y iw ) como en el escalar pasivo utilizado (isca). Tambien es necesario
indicar los pasos de tiempo para el perodo de muestreo empleado en las sondas (nthist) y para
el total de celdas (ntchr ). Cabe destacar que en ambos casos, el sistema almacena en archivos
los valores instantaneos medidos para la concentracion de escalar y las tres componentes de
velocidad. Salvo que se indique lo contrario, el muestreo en los sensores sera a cada paso de
tiempo y el muestreo general se realizara cada 10 paso a fines de obtener una representacion
completa del estado de la simulacion.
...

65
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

dtref = 0.061d0
ntmabs = 16000
...
!first order diffusivity: 0.0d0
!second order diffusivity: 1.0d0
blencv(iu(iphas)) = 1.0d0
blencv(iv(iphas)) = 1.0d0
blencv(iw(iphas)) = 1.0d0
...
blencv(isca(1)) = 0.0d0
...
nthist = 1
ntchr = 10
...

A continuacion se definen las variables fsicas aplicables al fluido: la viscosidad dinamica


(viscl0 ), las tres componentes de gravedad (gx , gy y gz ), la densidad (ro0 ), el calor especfico,
el valor de referencia de temperatura (t0 ) y de presion (p0 ). Salvo la viscosidad que tiene un
impacto directo en el numero de Reynolds, las otras variables fueron anuladas o llevadas a un
valor unitario para simplificar el desarrollo de la experiencia.
...
gx = 0.d0
gy = 0.d0
gz = 0.d0
...
ro0(iphas) = 1.d0
viscl0(iphas) = 1.d0/235.D0
cp0(iphas) = 1.d0
t0(iphas) = 1.d0
p0(iphas) = 0.d0
...

Ya definidas las variables fsicas y numericas, se debe especificar la ubicacion de cada sensor.
Code Saturne soporta hasta 100 sondas de prueba para las cuales se almacena las magnitudes
indicadas en archivos de texto especiales y con la frecuencia de muestreo correspondiente. En
este caso, se decide definir las sondas de forma generica, estableciendo areas para su colocacion
de forma equiespaciada. El siguiente extracto de codigo muestra la declaracion de la estructura
para indicar estas areas junto con las variables auxiliares necesarias:
! Declares a custom type which includes start and end coordinates for the probes area.
TYPE probes_area
double precision xStart
double precision yStart
double precision xEnd
double precision yEnd
double precision separation
END TYPE

!Declares auxiliary variables for the coordinates and separation between probes.
double precision xProbe, yProbe, xSeparationProbe, ySeparationProbe
integer iProbe, iProbeLine, iProbeArea

Luego, se definen las areas necesarias indicado la separacion, los lmites de inicio y de fin
para cada una. En este caso se utilizaron dos areas de sondas, una con Y positivas y la otra
dispuesta simetricamente con Y negativas. Las areas son configuradas como lneas paralelas al
eje X con separacion de 0,5 diametros. Esta disposicion comprende a la necesaria para el sistema
de control e incluye sondas extras que seran utilizadas con fines de inspeccion pero excluidas en
los distintos algoritmos.
!Defines two areas where the probes should be placed
TYPE(probes_area) probesAreas(2)

Captulo 4.3. Simulacion de la Experiencia 66


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

probesAreas(1) %xStart = 0.0


probesAreas(1) %xEnd = 20.0
probesAreas(1) %yStart = 1.0
probesAreas(1) %yEnd = 1.0
probesAreas(1) %separation = 0.5
probesAreas(2) %xStart = 0.0
probesAreas(2) %yStart = -1.0
probesAreas(2) %xEnd = 20.0
probesAreas(2) %yEnd = -1.0
probesAreas(2) %separation = 0.5

La coleccion de areas es recorrida y se almacena las coordenadas de cada sonda en xyzcap,


con coordenada Z nula:
do iProbeArea = 1, size(probesAreas), 1
ySeparationProbe = sign(probesAreas(iProbeArea) %separation, &
probesAreas(iProbeArea) %yEnd - probesAreas(iProbeArea) %yStart)
xSeparationProbe = sign(probesAreas(iProbeArea) %separation, &
probesAreas(iProbeArea) %xEnd - probesAreas(iProbeArea) %xStart)

xProbe = probesAreas(iProbeArea) %xStart


do while (((xSeparationProbe.ge.0).and.(xProbe.le.probesAreas(iProbeArea) %xEnd)) &
.or.((xSeparationProbe.lt.0).and.(xProbe.ge.probesAreas(iProbeArea) %xEnd)))

yProbe = probesAreas(iProbeArea) %yStart


do while (((ySeparationProbe.ge.0).and.(yProbe.le.probesAreas(iProbeArea) %yEnd)) &
.or.((ySeparationProbe.lt.0).and.(yProbe.ge.probesAreas(iProbeArea) %yEnd)))

iProbe = iProbe + 1
xyzcap(1,iProbe) = xProbe
xyzcap(2,iProbe) = yProbe
xyzcap(3,iProbe) = 0.00d0

yProbe = yProbe + ySeparationProbe


end do
xProbe = xProbe + xSeparationProbe
end do
end do
ncapt = iProbe

4.3.1.2. usclim.f90
La definicion de las condiciones fsicas implica identificar las celdas del mallado que participan
en cada una de los lmites de la experiencia. El mecanismo utilizado en este caso consiste en
asignar un numero que representa un color a cada una de las celdas lmite. Aquellas celdas que
requieran un tratamiento particular y la configuracion de condiciones de borde, seran filtradas
del resto para recibir la configuracion reservada por Code Saturne a tal fin.
El siguiente bloque de codigo, define las variables auxiliares necesarias junto con el mapeo
de bordes propuesto:
double precision alfa, beta
double precision xCentre, yCentre
real, parameter :: inputVelocity = 1d0
real :: upperActuatorValue, lowerActuatorValue

!Codigo de color, Nombre de Capa, Tipo de Lomite en CodeSaturne


!2, entrada, ientre + inyeccion de escalar
!3, salida, isolib
!4, pared, iparoi
!5, simetria, isymet
!7, actuador, iparoi + inyeccion de cantidad de movimiento

Captulo 4.3. Simulacion de la Experiencia 67


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

La pared del cilindro y el borde superior e inferior de simetra son de facil configuracion.
Simplemente es necesario seleccionar las celdas que poseen sus respectivos colores mediante
getfbr(filtro, cantEncontradas, listaEncontradas) y luego definir el tipo de borde (itypfb)
para cada cara de celda que cumpla con la condicion (ifac):
!pared -> iparoi
call getfbr(4, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

do iphas = 1, nphas
itypfb(ifac,iphas) = iparoi
enddo
enddo

!simetria -> isymet


call getfbr(5, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

do iphas = 1, nphas
itypfb(ifac,iphas) = isymet
enddo
enddo

La salida requiere configuraciones particulares sobre ciertos tipos de condiciones de borde


(icodcl ) y sus respectivos valores (rcodcl ) para magnitudes en las caras como ser la presion
(ipr ), velocidad en X (iu), Y (iv ) y Z (iw ).
!salida -> isolib
call getfbr(3, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)
iel = ifabor(ifac)
do iphas = 1, nphas
itypfb(ifac,iphas) = isolib

icodcl(ifac,ipr(iphas)) = 1 !dirichlet condition on pressure -> fixed value


icodcl(ifac,iu(iphas)) = 3 !neumann condition on velocity -> fixed gradient
icodcl(ifac,iv(iphas)) = 3
icodcl(ifac,iw(iphas)) = 3

rcodcl(ifac,ipr(iphas),1) = 0.0d0 !dirichlet value fixed to pressure=0


rcodcl(ifac,iu(iphas),3) = 0.0d0 !neumann value fixed to grad(u,normal) = 0
rcodcl(ifac,iv(iphas),3) = 0.0d0
rcodcl(ifac,iw(iphas),3) = 0.0d0
enddo
enddo

La entrada posee la complejidad extra de definir la zona de inyeccion de escalar para aquellas
caras que posean el color indicado y tengan un centro en Y (calculado mediante cdgfbo(color,
caraEncontrada)) entre las ordenadas 0,1 y 0,1. En estos casos, ademas de fijar la velocidad
unitaria en el eje X a la constante inputVelocity = 1 , se define un valor unitario al escalar
(isca).
!entrada -> ientre
call getfbr(2, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

do iphas = 1, nphas
itypfb(ifac,iphas) = ientre
rcodcl(ifac,iu(iphas),1) = inputVelocity
rcodcl(ifac,iv(iphas),1) = 0.0d0
rcodcl(ifac,iw(iphas),1) = 0.0d0

Captulo 4.3. Simulacion de la Experiencia 68


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

yCentre = cdgfbo(2,ifac)
do ii = 1, nscal
if(iphsca(ii).eq.iphas) then

if (yCentre.gt.-0.1d0.and.yCentre.lt.0.1d0) then
icodcl(ifac, isca(ii)) = 1
rcodcl(ifac, isca(ii),1) = 1.d0
else
icodcl(ifac, isca(ii)) = 0
rcodcl(ifac, isca(ii),1) = 0.d0
endif

endif
enddo
enddo
enddo

Por ultimo, se filtran los elementos que definen los semi-arcos de actuacion para entregarles
un tratamiento particular. Mediante simples calculos de geometra, se asignan los componentes
de velocidad en X e Y necesarios para obtener una inyeccion de movimiento tangencial a la pared.
Se agregan dos variables para definir la magnitud de dichas velocidades: upperActuatorValue
y lowerActuatorValue, ambas nulas para los fines de la simulacion inicial pero que seran
modificadas en cada iteracion cuando se defina el control para el cilindro.
upperActuatorValue = 0
lowerActuatorValue = 0

!actuador -> iparug


call getfbr(7 and y > 0, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

xCentre = cdgfbo(1,ifac)
yCentre = cdgfbo(2,ifac)
alfa = atan(yCentre / xCentre)
beta = alfa - pi/2.0

do iphas = 1, nphas
itypfb(ifac,iphas) = iparoi
rcodcl(ifac,iu(iphas),1) = upperActuatorValue * cos(beta)
rcodcl(ifac,iv(iphas),1) = upperActuatorValue * sin(beta)
rcodcl(ifac,iw(iphas),1) = 0.0d0
enddo
enddo

call getfbr(7 and y < 0, nlelt, lstelt)


do ilelt = 1, nlelt
ifac = lstelt(ilelt)

xCentre = cdgfbo(1,ifac)
yCentre = cdgfbo(2,ifac)
alfa = atan(yCentre / xCentre)
beta = alfa + pi/2.0

do iphas = 1, nphas
itypfb(ifac,iphas) = iparoi
rcodcl(ifac,iu(iphas),1) = lowerActuatorValue * cos(beta)
rcodcl(ifac,iv(iphas),1) = lowerActuatorValue * sin(beta)
rcodcl(ifac,iw(iphas),1) = 0.0d0
enddo
enddo

Captulo 4.3. Simulacion de la Experiencia 69


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

4.3.2. Resultados
Una vez configurada de la experiencia, se procede con la ejecucion de la simulacion y el analisis
de las mediciones obtenidas. La Fig. 4.3.1 muestra el avance del escalar inyectado generando un
filamento que difunde a traves del cilindro y demarca su burbuja de recirculacion. Una vez que la
experiencia entra en regimen, la aparicion de desprendimiento de vortices genera un movimiento
oscilatorio aguas abajo del cilindro que es adoptado por el trazador mediante las lneas de emision
(Fig. 4.3.2).

Figura 4.3.1: Inyeccion de trazador pasivo en el regimen inicial de la experiencia. Se puede observar la disposicion
de los sensores aguas abajo del cilindro, en posiciones no alcanzadas aun por el escalar.

Figura 4.3.2: Inyeccion de trazador pasivo en regimen oscilatorio de la experiencia. El desprendimiento de vortices
provoca un movimiento oscilatorio en la estela del cilindro que es copiado por el trazador.

Una magnitud caracterstica para este tipo de experiencias fsicas es la vorticidad que se
v
define como el rotor de la velocidad. En 2D se la puede expresar como (x, y, t) = x u
y ,
siendo u(x, y, t) y v(x, y, t) las velocidades instantaneas en el eje X e Y respectivamente. Esta
magnitud mide el grado de la rotacion local que sufre un punto (x, y) en el tiempo t entregando
valores negativos para una rotacion horaria y positivos para una anti-horaria. La Fig. 4.3.3
compara los valores de escalar y vorticidad instantanea una vez que se establece el regimen
oscilatorio.

Captulo 4.3. Simulacion de la Experiencia 70


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.3.3: Concentracion de escalar y vorticidad instantanea del flujo del cilindro. Realizando una comparacion
cualitativa de ambas magnitudes se puede observar la similitud entre los caminos optados por el trazador y los
vortices del camino de Von Karman.

La Fig. 4.3.4 entrega una vista de la variacion de la concentracion en los sensores 1 y 4 hasta
que el sistema entra en regimen oscilatorio. En la misma se puede observar el retardo temporal
que existe entre la informacion captada por cada sonda, producto de la distancia que poseen
respecto del cilindro.

Captulo 4.3. Simulacion de la Experiencia 71


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.3.4: Resultados de la concentracion de escalar medida por los sensores 1 y 4, el mas cercano y mas alejado
del cilindro respectivamente, durante la fase de inicio. Es posible apreciar el retardo que sufre el avance del escalar
por el frente izquierdo. Esto resulta evidente en las mediciones del sensor 4 respecto del 1 tanto en las primeras
concentraciones obtenidas como en las repetitivas oscilaciones que acompanan el desprendimiento de vortices.

Dado que la velocidad de muestreo es equivalente al paso de tiempo de la simulacion (t =


0,061), resulta mas apropiado realizar los graficos en funcion de esta magnitud. La Fig. 4.3.5
muestra los valores en cada uno de los sensores en funcion del paso de tiempo.

Captulo 4.3. Simulacion de la Experiencia 72


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.3.5: Evolucion de la concentracion del escalar media en los distintos sensores (probe 1..8). Se puede
observar la diferencia de fase entre la senal de los sensores superiores (probe 1..4) y sus respectivas contrapartes
inferiores (probe 5..8). Una vez alcanzado el regimen estacionario, las oscilaciones se identifican periodicas cada
87 muestras.

Si bien, las senales de concentracion de escalar entregan una discretizacion del fenomeno
real simulado, se observa claramente una oscilacion periodica para el sistema. Una medicion
detallada de la oscilacion permite obtener una aproximacion del perodo de la experiencia real.
De esta forma, se determina empricamente el perodo de oscilacion para la concentracion del
escalar en 87 muestras, es decir T = 87 0,061 = 5,307. Esto es as tanto para los sensores
cercanos al cilindro como para aquellos que se encuentran a mayor distancia.
Es importante comparar esta medicion con el numero de Strouhal estimado en el Captulo
3.3 en base al Re de la experiencia: Stestimado = 0,1814. Dado que tanto el diametro como la
velocidad caracterstica de la experiencia son unitarios, el valor de St coincide con la frecuencia
adimensional. Se puede aproximar el St real de la experiencia utilizando el T medido:
fD f 1
St = = = T 1 = 5,3071
U 1
= 0,884

Captulo 4.3. Simulacion de la Experiencia 73


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Luego, St resulta muy cercano al Stestimado e indica que las oscilaciones del escalar medido
estan relacionadas directamente con el desprendimiento de vortices. Mas aun, el perodo de los
desprendimientos se puede aproximar como el perodo de la senal medida en los sensores.

Captulo 4.3. Simulacion de la Experiencia 74


4.4 Comunicacion con el Sistema de Con-
trol

El sistema de control disenado requiere algun mecanismo para modificar el valor de actuacion
en Code Saturne de forma dinamica, esto es, frente a cada paso de tiempo.
Si bien las condiciones de borde pueden ser re-establecidas en cada iteracion de la simulacion
mediante codigo Fortran, este lenguaje resulta poco flexible, no posee buenas interfaces para
interactuar con aplicaciones matematicas (Matlab, Scilab, Octave, Etc.) y su manejo de meca-
nismos multi-threading posee muy poco soporte y escaso uso. Estos factores resultan importantes
si se piensa en la extension y reuso del sistema tanto para escenarios de simulacion como para
implementaciones experimentales. Por otro lado, los sistemas escritos en C y C++ se caracteri-
zan por permitir la interaccion con una gran cantidad de lenguajes y esquemas de comunicacion,
manteniendo a su vez un rendimiento de computo similar al de Fortran. Es importante remarcar
que tanto Fortran como C/C++ poseen interfaces para realizar GPGPU mediante plataformas
como CUDA. Sin embargo, la version CUDA C/C++ posee una mayor aceptacion y soporte por
tratarse de un lenguaje mas popular.

4.4.1. Lenguajes Utilizados


Se plantea entonces un sistema externo a Code Saturne, escrito en C++, que resuelva el
control de la experiencia mediante la lectura de los sensores y el calculo de actuacion requerida. A
fines practicos, se utiliza Matlab como utilitario de calculo matricial para resolver los algoritmos
de identificacion del sistema y de control por su alto contenido matematico. Cabe aclarar que
el objetivo principal de este esquema es obtener un entorno adecuado para implementar los
algoritmos descritos en los Captulos 3.4 y 3.5 debido a la complejidad matematica que poseen
y a la flexibilidad necesaria para verificar la correctitud de los resultados.
Aunque es conocida la diferencia en velocidad de ejecucion entre programas de Matlab y
C++, no se fijan requerimientos de performance particulares por tratarse de la etapa de si-
mulacion de la experiencia. De todas formas, se entiende que todo el codigo escrito en rutinas
de Matlab puede ser incluido en el sistema principal en C++ de una forma adecuada y, mas
aun, con la posibilidad de optimizar los tiempos de procesamiento de las secuencias altamente
paralelizables mediante GPGPU. Ese esquema posee grandes ventajas para una implementacion
real-time en laboratorio. La Fig. 4.4.1 presenta un esquema simplificado de la relacion entre los
distintos sistemas ideados que se detallan en las siguientes secciones.

75
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.4.1: Diagrama de bloques donde se muestra la dependencia entre los sistemas escritos en Fortran, C++
y Matlab. Se utiliza el nombre de archivo representativo para cada caso.

Incluso cuando la implementacion en laboratorio queda fuera del alcance del presente trabajo,
se realizaron distintos avances en tal direccion con el desarrollo de pruebas de concepto de los
algoritmos en CUDA C/C++(Apendice G.2) y de ejemplos de la obtencion programatica de
imagenes a partir de distintas camaras (Apendice G.1).

4.4.2. Interaccion entre Modulos


En primer lugar es importante comprender que la amplitud de actuacion en la pared del
cilindro se establece mediante las variables upperActuatorValue y lowerActuatorValue que
configuran las condiciones de borde en el archivo usclim.f90 (ver Captulo 4.3.1). Para el
objetivo particular de la experiencia elegida, se asume que ambas variables estan sincronizadas
y presentan la misma actuacion a cada instante de tiempo pero, de todas formas, el codigo del
controlador esta preparado para soportar variables independientes.
Dado que se desarrolla el controlador en un sistema externo, el problema se resume en
encontrar un mecanismo que detenga la ejecucion detallada en usclim.f90 frente a cada paso de
tiempo, notifique su numero al sistema externo, espere la respuesta de actuacion y modifique los
valores de upperActuatorValue y lowerActuatorValue. La Fig. 4.4.2 ilustra la dependencia
entre el sistema simulador y el controlador mediante un diagrama de actividades simple.

Captulo 4.4. Comunicacion con el Sistema de Control 76


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.4.2: Diagrama simple de las actividades del simulador y controlador. Se pueden observar la concurrencia
entre los ciclos principales de cada subsistema y la dependencia del simulador sobre los valores calculados por el
controlador.

Por otro lado, el sistema controlador debe obtener los valores medidos en los distintos sensores
y elaborar una actuacion ya sea durante el entrenamiento del sistema e identificacion del ARX o
durante el control de la estela. La actuacion de entrenamiento funciona en una fase inicial, donde
las muestras son acumuladas hasta contar con la cantidad suficiente para identificar el sistema.
Luego de calcular el modelo ARX, se lo utiliza con las muestras pasadas en el algoritmo de control
predictivo para calcular la actuacion que mejor ajusta la funcion objetivo. Esta secuencia nos
presenta 2 fases marcadas: la fase de entrenamiento y la fase de control. La identificacion del
sistema marca el punto de division entre ambas fases. En este caso, la muestra con los valores
de los sensores sera obtenida de los archivos generados por Code Saturne que almacenan las
mediciones en formato CSV a cada paso de tiempo. A tal fin, se implementa un Parser que
recolecta las muestras.
Las Fig. 4.4.3 presenta un diagrama de colaboracion simple que describe la secuencia de
comunicacion entre los modulos mencionados durante la fase de entrenamiento. Cuando las
muestras recolectadas alcanzan el numero necesario, se ejecuta el algoritmo de identificacion del
sistema y se entra en la fase de control a lazo cerrado (Fig. 4.4.4).

Captulo 4.4. Comunicacion con el Sistema de Control 77


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.4.3: Diagrama de colaboracion de la fase de entrenamiento.

Figura 4.4.4: Diagrama de colaboracion de la fase de control.

4.4.3. Implementacion
Se decide mantener la independencia de procesos entre ambos sistemas y emplear una es-
quema de comunicacion mediante pipes de sistemas operativos basados en Unix. Dado que la
comunicacion es bidireccional, se requieren dos archivos para establecer los canales de comuni-
cacion en cada sentido. Los pipes son creados por nombre a traves de archivos especiales FIFO
construidos con el comando mkfifo. El pipe de escritura para el simulador y lectura para el
controlador es llamado semaphore dado que permite senalizar al controlador en el momento
en que se requiere calcular el nuevo valor de actuacion. La senal incluye el numero de paso de
tiempo como parametro que resulta importante en el sistema controlador para recolectar las
muestras adecuadas mediante el Parser. El otro sentido de la comunicacion es representado por
los archivos act.upper y act.lower que permiten enviar los valores decimales de amplitud de
actuacion al simulador. Los descriptores de archivo son abiertos en cada sistema de modo blo-
queante, de esta forma, los sistemas intercalan mensajes y se esperan mutuamente mientras su
par realiza operaciones de calculo.
El siguiente bloque de codigo muestra la creacion de los pipes y el lanzamiento del proceso
controlador al que se le indican los nombres definidos. Luego, el simulador abre los archivos
especiales en modo escritura o lectura segun sea necesario. Esta secuencia de inicio se efectua
una unica vez gracias a la guarda de la variable estatica actuatorValuesInitialized :
if (.not.actuatorValuesInitialized) then

Captulo 4.4. Comunicacion con el Sistema de Control 78


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

call system("mkfifo semaphore")


call system("mkfifo act.upper")
call system("mkfifo act.lower")
call system("./controller act.upper.csv act.lower.csv" &
//" probes_Scalar1.dat < semaphore &")
open(unit=103, file="semaphore", action="write")
open(unit=104, file="act.upper", action="read")
open(unit=105, file="act.lower", action="read")

actuatorValuesInitialized = .true.
endif

Luego, frente a cada iteracion, el simulador escribe en el pipe el paso de tiempo (ntcabs) y
espera hasta que los valores de actuacion son notificados por los otros pipes:
write(sStepNumber, (i0) ) ntcabs
write(103,*) sStepNumber

read(104,*) upperActuatorValue
read(105,*) lowerActuatorValue

Por ultimo, al encontrarse en el paso de tiempo final de la simulacion (ntmabs), cierra los
descriptores indicando al controlador que la simulacion ha finalizado:
if (ntmabs.eq.ntcabs) then
close(103)
close(104)
close(105)
endif

El sistema controlador, por su parte, consta de un ciclo en el archivo main.cpp que emplea
una instancia de la clase SaturneCommunicator para esperar por el paso de tiempo (se-
maphoreStepNumber ) proveniente del pipe y enviar la actuacion (act.upper y act.lower )
por los pipes restantes. A su vez, se utiliza un objeto Parser para recolectar las mediciones en
el paso de tiempo anterior y un Controller para calcular la actuacion en base a las muestras.
El ciclo de control finaliza cuando se obtiene un paso de tiempo invalido.
...
Controller controller(/*...*/);
Parser parser(/*...*/);
SaturneCommunicator saturneCommunicator;

controller.initialize(/*...*/);
bool continueControl = true;
while (continueControl) {
int semaphoreStepNumber = saturneCommunicator.waitForStep(semaphore);
if (semaphoreStepNumber > 0) {
Row values = parser.readValues(probesPressureFilepath , semaphoreStepNumber - 1);
Actuation act = controller.getActuationFor(semaphoreStepNumber, values);

saturneCommunicator.send(upperActuator, act.upper);
saturneCommunicator.send(lowerActuator, act.lower);
}
else {
continueControl = false;
}
}
...

Resulta interesante observar que la implementacion de los metodos de espera (waitForS-


tep) y envo (send ) que posee la clase SaturneCommunicator se implementan con simples
operaciones de lectura y escritura bloqueantes en los archivos que representan los pipes:

Captulo 4.4. Comunicacion con el Sistema de Control 79


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

int SaturneCommunicator::waitForStep(std::istream& semaphore) {


unsigned int semaphoreStepNumber;
semaphore >> semaphoreStepNumber;
if (semaphore.good()) {
return semaphoreStepNumber;
else
return 0;
}

void SaturneCommunicator::send(std::ofstream& actuatorFile, double value) {


std::stringstream converter;
converter << value;

std::string strValue;
converter >> strValue;
actuatorFile << strValue <<std::endl;
}

El detalle del sistema controlador as como las distintas abstracciones utilizadas puede en-
contrarse en el Apendice F.6.

Captulo 4.4. Comunicacion con el Sistema de Control 80


4.5 Identificacion del Sistema

La fase de identificacion del sistema tiene por objetivo la obtencion de un modelo ARX que
ajuste de la mejor manera al modelo fsico simulado. A tal fin, se utiliza el sistema controlador
para forzar una senal de actuacion predeterminada, capturar las muestras en los sensores durante
N pasos de tiempo e identificar el modelo ARX de orden p mediante una implementacion en
Matlab del algoritmo introducido en el Captulo 3.4.

4.5.1. Entrenamiento del Sistema


Como senal de entrenamiento se escoge un pulso de gran altura y corta duracion. Este tipo
de senal es ampliamente utilizada para evaluar la respuesta de sistemas debido a la variedad de
frecuencias que posee. La duracion del pulso se establece en 10 pasos de tiempo y la amplitud
en 10. Estos valores demuestran de forma emprica que son suficientes para obtener un cambio
significativo en la dinamica de la estela con un efecto estabilizador durante un lapso corto de
tiempo.
La identificacion del sistema se realiza con una medicion de N = 1090 muestras totales y con
un pulso iniciado en el paso de tiempo 90. Como fuera descrito en el Captulo 3.3, la cantidad
de sensores que define al sistema es de m = 8 mientras que la cantidad de componentes de la
actuacion es r = 1. Los resultados pueden observarse en la Fig. 4.5.1.

81
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.5.1: Fase de entrenamiento del sistema. Se puede observar la evolucion de la concentracion del escalar en
las 8 sensores en relacion con el pulso forzado en la actuacion. Los graficos del escalar muestran que el efecto del
pulso posee un retardo dependiendo de la distancia del sensor a la zona de actuacion. Tambien es posible observar
que el desfasaje constante que existe entre senales de sensores simetricas es afectado por la actuacion durante un
breve perodo de tiempo.

Luego de cierto tiempo de disparar el pulso, la concentracion del escalar se reduce drastica-
mente en los distintos sensores. Considerando el flujo como un sistema dinamico no lineal, las
variables de estado orbitan alrededor de un centro de atraccion [65]. El pulso forzado perturba
dicha orbita de forma abrupta para luego entrar en una etapa de relajacion. La orbita de oscila-
cion natural es retomada gradualmente a medida que el sistema entra en regimen. El retardo de
control (death-time) se explica por la distancia de los sensores al punto de actuacion y aumenta

Captulo 4.5. Identificacion del Sistema 82


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

gradualmente a medida que el sensor se aleja.


El orden del modelo ARX, p, define la cantidad de muestras para el horizonte de autoregre-
sion y debe ser establecido de forma tal que el modelo capture las relaciones entre los distintos
componentes del vector de estado. En efecto, el valor de p, establece una ventana temporal
donde las mediciones y actuacion se vinculan mediante los coeficientes del modelo. Si la ventana
es muy pequena, el modelo no captura efectos que cierta variable (por ejemplo, la actuacion)
causa en otra (por ejemplo, un sensor arbitrario) en casos donde la reaccion posee un retardo
mayor al tamano de ventana. Una ventana muy grande, ademas de requerir cantidades excesivas
de procesamiento para el calculo y uso del modelo, puede resultar innecesaria si los efectos de
una variable sobre otra tienen retrasos temporales mucho menores a la ventana. Como agre-
gado se conoce que a mayor p se obtiene un mejor ajuste del modelo frente a la respuesta del
entrenamiento con el costo de aumentar su sensibilidad frente a ruidos.
A fines practicos se elige un valor de p = 90, levemente mayor al perodo natural de la
experiencia. Como se puede observar en el Apendice C.1, este valor de p asegura un ajuste
promedio del 99,7 % entre los valores reales obtenidos de la fase de entrenamiento y los valores
de prediccion que puede realizar el modelo ARX.

4.5.2. Implementacion del Algoritmo


El calculo del modelo escrito en Matlab se dispara desde el sistema controlador en C++
utilizando la interfaz provista por las libreras MEX de Matlab. Este comportamiento es encap-
sulado en la clase MatlabExecutor que interactua con la interfaz MEX transmitiendo datos
y operaciones. Para facilitar su uso, se construye la abstraccion Matrix que almacena valores
double en formato matricial. La interfaz de MatlabExecutor incluye operaciones para definir
variables matriciales, obtener su valor o evaluar expresiones matematicas como se muestra a
continuacion:
class MatlabExecutor {
private:
Engine *ep;
//...
public:
MatlabExecutor(/* ... */);
~MatlabExecutor();
void putMatrix(const std::string& matrixVariableName, Matrix& values);
Matrix getMatrix(const std::string& matrixVariableName);
void evaluate(const std::string& expression);
double evaluateScalar(const std::string& expression);
};

La implementacion completa, las clases Matrix y MatlabExecutor , as como su modo de


uso puede encontrarse en el Apendice F.6.
El caso particular de la identificacion del sistema se resuelve evaluando la funcion lfd arx ,
de Matlab. La funcion calcula las matrices A y B de orden p del modelo ARX en base a las
mediciones y y u indicadas por el sistema controlador:
function [A B] = lfd_arx(y, u, p)

Se definen las variables na y nb respecto del orden del modelo p y se obtiene m, r , N de


las dimension de los vectores de muestras para agrupar sus valores en la variable (k), llamada
phi , segun la Ec. 3.4.2:
na = p;
nb = na+1;
[m,N] = size(y);

Captulo 4.5. Identificacion del Sistema 83


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

[r,N] = size(u);

phi = zeros(na*m+nb*r,N);
for j=na+1:N
phi(:,j)=[reshape(-y(:, j-1:-1:j-na), na*m, 1); ...
reshape(u(:, j:-1:j-(nb-1)), nb*r, 1)];
end

Luego se calcula la matriz de regresion (k), llamada reg , utilizando el producto de Kro-
necker sobre los valores de (k):
phi_aux = fi(:, na+1:end);
reg = zeros(m*size(phi_aux,1), m*(N-na));
for j=1:N-na
reg(:, 1+(j-1)*m:j*m) = kron(phi_aux(:,j), eye(m));
end

Finalmente, se obtiene R de una descomposicion QR sobre la matriz de regresion y las


entradas para estimar el valor de , llamado th, segun la Ec. 3.4.4:
yna = y(:, na+1:end);
Y = reshape(yna, m*(N-na), 1);
R = triu(qr([reg Y]));
d = na*m*m+nb*r*m;
R0 = R(1:d+1,1:d+1);
R1 = R0(1:d,1:d);
R2 = R0(1:d,end);
th = pinv(R1) * R2;

Por ultimo, los coeficientes i y i son extrados del estimador y organizados en las matrices
del modelo: A y B.
a = zeros(m, m, na);
b = zeros(m, r, nb);
for j=1:na
a(:,:,j)=reshape(th(1+(j-1)*m*m:j*m*m),m,m);
end
for j=1:nb
b(:,:,j)=reshape(th(1+na*m*m+(j-1)*m*r:1+na*m*m+(j-1)*m*r+m*r-1),m,r);
end

A = zeros(m, m, na+1);
A(:,:,1) = eye(m);
A(:,:,2:end) = a(:,:,:);
B = b;

El codigo completo del calculo del modelo ARX se puede encontrar en el Apendice F.5 junto
con la version implementada en CUDA C/C++ (Apendice G.2.
El Apendice C.2 presenta una breve comparacion sobre las diferencias en los tiempos de
procesamiento requeridos por la version Matlab y CUDA C/C++ del algoritmo.

4.5.3. Verificacion del Modelo ARX


Para verificar la validez del modelo se utiliza una senal de excitacion distinta a la empleada
durante la fase de entrenamiento y se simula su respuesta mediante Code Saturne. Las mediciones
resultantes de concentracion de escalar son comparadas con predicciones obtenidas del modelo
ARX. En tal sentido se plantea el uso de la rutina compare de Matlab para predecir los valores
de yi (k) y disponerlos graficamente juntos a los medidos. La prediccion utiliza un horizonte de
s = 90 pasos de tiempo en dos escenarios distintos donde se utiliza como entrada de actuacion

Captulo 4.5. Identificacion del Sistema 84


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

a la superposicion de ciertas senales gaussianas de la forma:


(t)2
g(t) = A e( 2 2
)

donde A indica la amplitud, la media de la campana y su desvo estandar. El valor de difiere


entre las distintas senales para desplazarlas entre s. Se utiliza cierto perodo de repeticion para
el corrimiento de las senales que permite calcular una frecuencia caracterstica de la actuacion
resultante.
El primer escenario superpone gaussianas de A = 0,55 y = 20 con un desplazamiento entre
1
de 70 pasos de tiempo. Esto implica una frecuencia caracterstica de = 0,2342 que
70 0,061
equivale aproximadamente a un 125 % de la frecuencia natural de la experiencia (0,1884). Esta
diferencia de frecuencias es pequena y permite lock-in entre la dinamica del desprendimiento
de vortices y la frecuencia impuesta por el actuador. En esos casos se observa que el sistema
modifica su frecuencia de oscilacion debido a la influencia de la senal de excitacion y su frecuencia
(Fig. 4.5.2).

Captulo 4.5. Identificacion del Sistema 85


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.5.2: Comportamiento del modelo frente a una actuacion de frecuencia 0,2342 con A = 0,55 y = 20.
Los graficos superiores presentan la evolucion en la concentracion del escalar a lo largo del tiempo para distintos
sensores. El grafico inferior muestra la senal aplicada simultaneamente a ambos actuadores.

En el segundo caso se utiliza A = 0,60 y = 20 con un desplazamiento entre de 45 pasos


1
de tiempo. Esto implica una frecuencia de = 0,3643 equivalente a 193 % de la frecuen-
45 0,061
cia original. Se observa un comportamiento satisfactorio del modelo pudiendo reproducir las
frecuencias principales de las oscilaciones de la experiencia. La concordancia de las predicciones
con la respuesta fsica resulta evidente en la etapa sin actuacion forzada y disminuye al iniciar el
control pero sin observarse diferencias considerables. El sistema resulta estable durante el lapso
de actuacion y retorna al estado de equilibrio al finalizar (Fig. 4.5.3).

Captulo 4.5. Identificacion del Sistema 86


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.5.3: Comportamiento del modelo frente a una actuacion de frecuencia 0,3643 con A = 0,60 y = 20.
En los graficos superiores se observa la evolucion en la concentracion del escalar a lo largo del tiempo para
distintos sensores. El grafico inferior muestra la senal aplicada simultaneamente a ambos actuadores. Se incluye la
respuesta del sistema al cesar la actuacion pudiendose observar que las predicciones mejoran gradualmente hasta
que el sistema entra nuevamente en regimen.

Realizando un analisis de frecuencia de la senales simuladas en comparacion con las pre-


dicciones, se encuentra una gran similitud en los patrones de frecuencia resultantes. En ambos
casos se analiza el numero de Strouhal de la experiencia entendiendo que, por las dimensiones
utilizadas para la simulacion, St = f . Las frecuencias caractersticas de la experiencia se mo-
difican levemente durante el perodo de control, hecho que es captado por las predicciones del
sistema (Fig. 4.5.4 y 4.5.5).

Captulo 4.5. Identificacion del Sistema 87


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.5.4: Espectrogramas de la verificacion del modelo mediante una senal de frecuencia 0,2342 (125 % respecto
de la caracterstica del sistema). Se compara el espectrograma de la simulacion (izquierda) y de las predicciones
del modelo ARX obtenido en la fase de identificacion del sistema.

En el caso extremo de frecuencia de actuacion 0,2342 (Fig. 4.5.5), la prediccion del modelo
agrega un componente de alta frecuencia a las salidas que el sistema real no posee. Esto puede
estar relacionado con la saturacion de la dinamica del flujo inducida por las no-linealidades que
estan ausentes en el modelo lineal ARX. Un simple analisis de Fourier sobre la parte periodica
de las senales de actuacion demuestra la componente de alta frecuencia no es introducida por el
actuador, al menos no directamente (Fig. 4.5.6). El analisis de frecuencia para ambas actuaciones
presenta picos para componentes que coinciden con las frecuencias estimadas de 0,2342 y 0,3643,
correspondientes al 125 % y 193 % de la caracterstica.

Figura 4.5.5: Espectrogramas de la verificacion del modelo mediante una senal de frecuencia 0,3643 (193 % respecto
de la caracterstica del sistema). Se compara el espectrograma de la simulacion (izquierda) y de las predicciones
del modelo ARX obtenido en la fase de identificacion del sistema.

Captulo 4.5. Identificacion del Sistema 88


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.5.6: Analisis de frecuencia de las senales de actuacion utilizadas para la verificacion del modelo ARX.
Se elimina la componente media para mayor claridad de espectro de frecuencias relevante. Sup.: Modulo de la
transformada de Fourier de la senal de gaussianas superpuestas con frecuencia 0,2342. Inf.: De forma analoga al
anterior, se analizan los componentes de Fourier de la senal de gaussianas con frecuencia 0,3643.

Captulo 4.5. Identificacion del Sistema 89


4.6 Sistema de Control a Lazo Cerrado

Luego de identificado el modelo ARX, el sistema deja la fase de entrenamiento para entrar en
modo de control a lazo cerrado. Esta fase se caracteriza por requerir el calculo inicial de ciertos
parametros que seran reutilizados en operaciones mas simples en iteracion de la simulacion. Este
paso es disparado una unica vez por el subsistema C++ efectuando el computo en Matlab. A
su vez, las muestras y valores de actuacion son acumulados en C++ para ser utilizados en la
invocacion de una nueva funcion en Matlab frente a cada paso de tiempo.

4.6.1. Implementacion del Algoritmo


4.6.1.1. Inicializacion
Al entrar en la fase de control, el sistema C++ inicia el estado del subsistema Matlab cal-
culando control state. Esta estructura almacena los parametros basicos del controlador, p, s,
q y , junto con la matriz de control, K, calculada en base al modelo ARX (Ec. 3.5.5). La
implementacion incluye una variable limits que permite definir mnimo y maximo permitidos
para la actuacion.
function [ control_state ] = lfd_control_lagrange_init(y, u, p, lambda, A, B, limits, q)

En primer lugar se determinan las dimensiones del sistema en base a la cantidad de compo-
nentes del vector de estado y el paso actual de tiempo es asumido sobre la cantidad de muestras:
m = size(y,1);
r = size(u,1);
s = 3*p;
k = size(y,2);

El horizonte de prediccion se fija en s = 270, 3 veces el valor de p. Esta cantidad indica los pasos
de tiempo proyectados por el controlador hasta conseguir una actuacion estable (sin variaciones).
Se opta por emplear un valor de s elevado para evitar un controlador agresivo respecto de la
proyeccion del valor de actuacion optimo y el tiempo para conseguirlo. De esta forma se pretende
contemplar la naturaleza oscilatoria del sistema y la posibilidad de oscilaciones en el control del
orden de 3 veces el perodo caracterstico del fenomeno. A su vez, se tiene conocimiento de
resultados exitosos en experiencias de control similares con 2p s 3p [35, 36].
A continuacion, se transforma el modelo ARX a la convencion propuesta en [33] que presenta
ciertas facilidades en su manipulacion. Luego, se calculan los parametros del sistema de Markov,
(1) (s1)
0 , 0 , . . . 0 :
a = -A(:,:,2:end);
b = B;
beta00 = b(:,:,1);
beta0 = zeros(m, r, s-1);
beta0(:,:,1) = b(:,:,2) + a(:,:,1)*beta00;

90
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

for kk=2:s-1
if kk<=p
aux=zeros(size(beta00));
for l=1:kk-1;
aux=aux+a(:,:,l)*beta0(:,:,kk-l);
end
aux=aux+a(:,:,kk)*beta00;
beta0(:,:,kk) = b(:,:,kk+1)+aux;
else
aux=zeros(size(beta00));
for l=1:p;
aux=aux+a(:,:,l)*beta0(:,:,kk-l);
end
beta0(:,:,kk)=aux;
end
end

Con estos valores se conforma T segun Ec. 3.5.2:


T=zeros(m*s,r*s);
T_column =zeros(m*s,r);

T_column(1:m,:)=beta00;
for j=2:s;
T_column((j-1)*m+1:j*m,:)=beta0(:,:,j-1);
end;

for column = 1:s


T(m*(column-1)+1:m*s, r*(column-1)+1:r*column) = T_column(1:(m*s - (column-1)*m),:);
end;

Luego se calculan las relaciones recursivas de 1k , kj y kj en las variables alpha y beta:


psi=zeros(m*s,p*(m+r));
for kk=1:p-1;
alpha(:,:,1,kk)=a(:,:,1)*a(:,:,kk)+a(:,:,kk+1);
end;
alpha(:,:,1,p)=a(:,:,1)*a(:,:,p);

for j=2:s-1;
for kk=1:p-1;
alpha(:,:,j,kk)=alpha(:,:,j-1,1)*a(:,:,kk)+alpha(:,:,j-1,kk+1);
end;
alpha(:,:,j,p)=alpha(:,:,j-1,1)*a(:,:,p);
end

for kk=1:p-1;
beta(:,:,1,kk)=a(:,:,1)*b(:,:,kk+1)+b(:,:,kk+2);
end
beta(:,:,1,p)=a(:,:,1)*b(:,:,p+1);

for j=2:s-1;
for kk=1:p-1;
beta(:,:,j,kk)=alpha(:,:,j-1,1)*b(:,:,kk+1)+beta(:,:,j-1,kk+1);
end;
beta(:,:,j,p)=alpha(:,:,j-1,1)*b(:,:,p+1);
end

que permiten definir , llamada psi , segun la Ec. 3.5.3:


psi(1:m,:) = [reshape(a, m, m*p) reshape(b(:,:,2:end), m, r*p)];
for j=2:s
psi((j-1)*m+1:j*m,:) = [reshape(alpha(:,:,j-1,:), m, m*p) reshape(beta(:,:,j-1,:), m, r*p)];
end

Captulo 4.6. Sistema de Control a Lazo Cerrado 91


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Con las matrices T y definidas, se calculan las primeras r filas de la matriz de control K
(Ec. 3.5.5) utilizando q y . Tanto la variable de resultado, K r , como los parametros de inicio
son almacenados en control state:
Q=kron(eye(s), diag(q));
invLambdaTTQT = -pinv(lambda*eye(r*s) + T*Q*T);
control_state.K_r = invLambdaTTQT(1:r, :) * T * Q * psi;;
control_state.p = p;
control_state.limits = limits;
control_state.s = s;
control_state.m = m;
control_state.r = r;
control_state.lambda = lambda;

4.6.1.2. Iteracion de Control


Ya inicializado el estado del control, se ingresan los valores y(k) medidos en los sensores y
el u(k) utilizado en un paso de tiempo para calcular u(k + 1), la actuacion del siguiente paso.
La funcion lfd control lagrange recibe dichos valores y retorna control state modificado
incluyendo la actuacion calculada:
function control_state = lfd_control_lagrange(control_state, y, u)

En primer lugar, se define el paso de tiempo k sobre el cual se realizara el calculo y se


recuperan las variables de la estructura del estado para facilitar su uso:
k = size(y, 2) + 1;
limits = control_state.limits;
p = control_state.p;
m = control_state.m;
r = control_state.r;
K_r = control_state.K_r;

Se conforma el vector columna vp (k p) con los valores pasados de y(k) y u(k). Luego, se
utiliza el vector junto con las r filas calculadas de la matriz de control, K r , para obtener la
nueva actuacion segun la ley de control establecida en Ec. 3.5.7:
vp = zeros(p*m+p*r, 1);
for i=1:p
vp((i-1)*m+1:i*m) = y(:,k-i);
end
offset = m*p;
for i=1:p
vp((i-1)*r+1+offset:i*r+offset) = u(:,k-i);
end;

u_k = K_r * vp;

Por ultimo, se utilizan los lmites definidos con anterioridad para eliminar valores de actua-
cion fuera de los rangos aceptados por la experiencia:
indices_out_of_limit = find(u_k < limits.min_value);
u_k(indices_out_of_limit) = limits.min_value;
indices_out_of_limit = find(u_k > limits.max_value);
u_k(indices_out_of_limit) = limits.max_value;
control_state.u_k = u_k;

A modo de sntesis, la Tabla 4.6.1 resume los valores de los parametros de ajuste utilizados
en el algoritmo de control. El resultado de control demostro ser muy sensible a la definicion de

Captulo 4.6. Sistema de Control a Lazo Cerrado 92


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

dichos valores. Los ajustes finales requirieron un trabajo de comparacion manual y de reiteradas
simulaciones a fin de balancear el efecto conjunto de los parametros.

Parametro Variable Valor


Orden del Modelo p 90
Horizonte de Prediccion s 270
Paso de Tiempo Simulacion t 0.061
Peso de Sensores Sup. q1 , q2 , q3 , q4 1,4, 1,4, 1,4, 1,4
Peso de Sensores Inf. q5 , q6 , q7 , q8 1,4 1,4 1,4 1,4
Costo del Controlador 0,4

Tabla 4.6.1: Valores definidos para los distintos parametros de control del sistema.

4.6.2. Resultados de Control


A fines de verificar la respuesta del algoritmo de control, se ejecuta una nueva simulacion en
la cual se activa el controlador luego de acumular las suficientes muestras para calcular y utilizar
la matriz de control. En el sistema C++ se incluye la posibilidad de almacenar y recuperar el
modelo ARX debido a sus altos tiempos de computacion respecto de las operaciones de control.
Se emplea entonces el modelo ARX calculado en la fase de entrenamiento, previamente guardado
en archivos de datos Matlab, y se activa el controlador obteniendo una actuacion que estabiliza
la estela (Fig. 4.6.1).

Captulo 4.6. Sistema de Control a Lazo Cerrado 93


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.1: Resultados del sistema de control a lazo cerrado. Se puede observar el efecto de la amplitud de
actuacion sobre la concentracion del escalar en los distintos sensores en funcion del tiempo.

La senal de actuacion resultante presenta un caracter oscilatorio marcado, donde los mo-
vimientos ascendentes (descendientes) del actuador generan una reduccion (incremento) en el
escalar medido en los sensores. De acuerdo con la posicion del sensor respecto de la actuacion,
es necesario considerar un retardo temporal variable.
La estabilizacion de la estela del cilindro puede apreciarse en imagenes instantaneas de las
lneas de emision (Fig. 4.6.2) que difieren del escenario sin actuacion y se mantienen limitadas
en la zona del tunel de sensores. Por su parte la vorticidad instantanea (Fig. 4.6.3) disminuye
considerablemente respecto de los valores originales.

Captulo 4.6. Sistema de Control a Lazo Cerrado 94


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.2: Lneas de mision y valores de la concentracion del escalar en los sensores durante la fase de actuacion.
Es posible observar el efecto del control que restringe las lneas de mision al interior del tunel de sensores.

Figura 4.6.3: Vorticidad instantanea y valores en las sondas durante la fase de control. Los valores detectados
resultan menores que las mediciones en un escenario sin actuacion.

La frecuencia de oscilacion de la entrada genera entonces una oscilacion en la salida. Es


interesante observar que las oscilaciones caractersticas del fenomeno se mantienen con una
frecuencia similar a la original dentro de la envolvente de menor frecuencia. En la Fig. 4.6.4
se puede observar el espectro de frecuencias de actuacion con un componente muy marcado en
torno a frecuencias de 0,05 correspondiente al 26 % de la frecuencia caractersticas del fenomeno
(0,1884). Las Figs. 4.6.5 y 4.6.6 entregan una comparacion de la frecuencias de la salida medida
en los sensores 1, 2, 3 y 4 para los casos sin actuacion y con actuacion. En el segundo caso se

Captulo 4.6. Sistema de Control a Lazo Cerrado 95


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

puede observar la aparicion de un componente de 0,05 inducido por la actuacion, preponderante


sobre las otras frecuencias. La frecuencia caracterstica original (Aprox. 0,19) y sus armonicos
(0,38, 0,57, Etc.) de menor amplitud se pueden encontrar en las senales controladas pero con
una importante dispersion en torno a sus valores originales.

Figura 4.6.4: Analisis de frecuencias de la actuacion. Modulo de la transformada de Fourier de la entrada menos
su media.

Figura 4.6.5: Analisis de frecuencias de la senal de salida para los sensores 1 y 2. Se puede comparar el modulo
de la transformada de Fourier de la senal menos su media para el caso sin actuacion (Izq.) respecto del caso con
actuacion (Der.).

Captulo 4.6. Sistema de Control a Lazo Cerrado 96


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.6: Analisis de frecuencias de la senal de salida para los sensores 3 y 4. Se puede comparar el modulo
de la transformada de Fourier de la senal menos su media para el caso sin actuacion (Izq.) respecto del caso con
actuacion (Der.).

Es importante destacar la reduccion en la amplitud de los componentes de frecuencia, indi-


cando una disminucion del trazador captado por los sensores. Se puede atribuir este resultado al
comportamiento de las lneas de mision que se concentran ahora dentro del tunel de sensores.
A su vez, esto coincide con el descenso en el valor medio detectado en cada sensor segun se puede
observar en la Tabla 4.6.2.

Media y1 y2 y3 y4 y5 y6 y7 y8
Sin Actuacion 0,077 0,071 0,063 0,058 0,077 0,071 0,064 0,057
Con Actuacion 0,043 0,047 0,051 0,054 0,043 0,046 0,050 0,054

Tabla 4.6.2: Valores medios del escalar en los distintos sensores. Se puede ver un claro descenso de los valores de
concentracion medidos sin el controlador y con el controlador. La disminucion posee un porcentaje mayor en los
sensores mas cercanos al punto de actuacion.

4.6.2.1. Analisis de Energa y RMS de las Fluctuaciones en la Estela


Un posible criterio de estabilizacion de flujos consiste en el calculo de la energa cinetica
de la turbulencia (Turbulent Kinetic Energy o TKE) en el estado original y compararlo con la
obtenida durante el ciclo de control. El calculo de la TKE se basa en el principio de separacion
de variables en las partes media y turbulenta de cierta senal [63]. La parte media es constante y
caracteriza el comportamiento estacionario del flujo mientras que la parte turbulenta depende
del tiempo y, por lo tanto, se relaciona a la dinamica del mismo. Con este esquema es posible
describir la velocidad u(t) de una partcula segun:

u(t) = u + u0 (t)

donde u es la velocidad media y u0 (t) representa la velocidad de perturbaciones o turbulencias


(Fig. 4.6.7). Luego, el calculo de la energa cinetica sobre la componente fluctuante de la velocidad
entrega la TKE. En el caso de 2D y sumando los aportes de cada partcula sera:
1X 0 2 2
T KE(t) = (ux (t) + u0y (t) )
2

Captulo 4.6. Sistema de Control a Lazo Cerrado 97


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

La formula anterior debe entenderse como el calculo de energa por unidad de masa, siendo
T KE(t)/m una definicion mas rigurosa. Luego, los valores de TKE calculados para cada celda
de la simulacion se pueden integrar solo si se asume que poseen masa homogenea. Esto es una
buena aproximacion en el caso de celdas de identico tamano pero no puede asegurarse en el
mallado no estructurado aplicado a la experiencia (Captulo 4.2).
Para resolver este problema y permitir el analisis detallado del campo de velocidades re-
sultante de la experiencia, se implementa un sistema de transformacion para mallas irregulares
definidas por polgonos 2D en mallas regulares con celdas cuadradas de cierto tamano prefijado.
La Fig. 4.6.8 entrega una vista de la malla original y la conversion a una grilla de celdas regula-
res. Sabiendo que los celdas de la malla original varan de tamano entre 0,03 y 0,1, se opta por
generar una grilla con celdas cuadradas de lado 0,045 que permita captar el detalle de las celdas
pequenas en las cercanas del cilindro.

Figura 4.6.7: Representacion grafica de la composicion de una senal (u(t)) mediante sus partes media (u) y
perturbaciones o turbulencias (u0 (t)). La dinamica de la senal original queda caracterizada por u0 (t) mientras que
u responde al comportamiento estacionario (basado en Stull, 2008) [63].

Figura 4.6.8: Conversion de valores medidos en malla irregular a una grilla homogenea. Sobre el mallado original
(Izq.) se dispone una grilla celdas cuadradas (Der.). A modo de ejemplo, se colorean los triangulos del mallado
original que participan en una celda cuadrada del nuevo mallado (resaltada en rojo). Las superficies parciales
de color rojo participan en la composicion de la magnitud fsica mientras que las naranjas no lo hacen por ser
proyectadas fuera del cuadrado.

La transformacion se realiza generando una grilla cartesiana con celdas de identico tamano,
recorriendo cada celda de la grilla y proyectando en ella las celdas originales de la malla. Para
cada celda de la nueva grilla se recorren las celdas de la malla original calculando el porcentaje
de superposicion en la proyeccion. Luego, la magnitud fsica de la celda cuadrada se compone
del aporte pesado de las celdas originales proyectadas en ella.
De esta forma, cada celda de la malla irregular puede aportar a una o mas celdas de la grilla
regular. El codigo de conversion puede ser encontrado en el Apendice F.2 e incluye la lectura de

Captulo 4.6. Sistema de Control a Lazo Cerrado 98


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

los archivos CHR de salida de la simulacion Code Saturne. Dichos archivos poseen informacion
escalar (como la concentracion de trazador pasivo) o vectorial (como las componentes del campo
de velocidades) en formato Ensight Gold [12] que permite post-procesamiento y visualizacion de
los valores para una geometra de la experiencia.
Luego de obtener la conversion a una grilla homogenea, se calcula el TKE instantaneo en
la superficie que comprende la region bajo estudio. Un analisis detallado de la TKE demuestra
que la energa asociada con las fluctuaciones disminuye considerablemente luego de iniciado
el ciclo de control (Fig. 4.6.9). El cambio observado en el escenario controlado respecto de la
experiencia sin control corresponde a una reduccion de aproximadamente el 85 % del TKE. El
codigo de implementacion puede ser encontrado en el Apendice F.3.

Figura 4.6.9: Valores de la Energa Cinetica de la Turbulencia (TKE) instantanea en la transicion del sistema al
activar el controlador. Los valores fueron normalizados por unidad de superficie con una discretizacion cuadrada
de 0,045 y corresponden a la region definida por 5 < x < 20, 5 < y < 5. El controlador es activado en el paso
de tiempo 500 provocando una cada del TKE de aproximadamente el 85 %. Se incluyen los valores medios antes
y despues de iniciado el control a modo de referencia.

El impacto del control puede apreciarse tambien en el grafico del desvo estandar (Standard
Deviation o STD) de la velocidad en el sentido del flujo. En este caso se toma la componente X
del campo de velocidades en cada paso de tiempo y se calcula el STD para cada celda segun:
v
u
u1 X N
ST D = t (ujx (k) j )2 ,
N
k=1

donde ujx (k) corresponde a la velocidad en X para una celda arbitraria j y j indica el valor
medio calculado en dicha celda. Esta medida es similar al concepto de media cuadratica (Root
Mean Square o RMS) salvo que en esta ultima no se considera el valor de la media:
v
u
u1 X N
RM S = t (ujx (k))2 ,
N
k=1

En el caso particular de senales con media nula, los valores de STD coinciden con RMS. Por otro
lado, resulta claro que el calculo del RMS sobre las fluctuaciones de la velocidad (ujx (k) j )
coincide exactamente con su calculo de STD.

Captulo 4.6. Sistema de Control a Lazo Cerrado 99


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Realizando el calculo del RMS de las fluctuaciones para cada celda se puede obtener un grafico
que entregue una idea de la dispersion en las velocidades para el escenario sin actuacion (Fig.
4.6.10) y para el controlado (Fig. 4.6.11). Se puede observar que el sistema de control modifica
la dispersion del campo de velocidades concentrando las fluctuaciones dentro del tunelde
sensores.

Figura 4.6.10: RMS de las fluctuaciones de la velocidad en X para el escenario sin control. La lnea horizontal en
y = 0,415 atraviesa el valor maximo del RMS en el hemisferio superior.

Figura 4.6.11: RMS de las fluctuaciones de la velocidad en X para el escenario controlado. La lnea horizontal en
y = 0,280 atraviesa el valor maximo del RMS en el hemisferio superior.

En ambas figuras se traza una lnea sobre la ordenada que posee el valor maximo en el
hemisferio superior. La simetra del problema garantiza un comportamiento similar en el inferior
(no incluido en el analisis). Graficando el valor del RMS a lo largo de dicha lnea se puede
comparar el descenso marcado de los valores del RMS maximos de un escenario al otro (Fig.
4.6.12). A su vez, el valor pico se mueve de la lnea definida por y = 0,415 en el caso sin actuacion
a y = 0,280 en el caso controlado, demostrando el efecto de estabilizacion en la estela. Estos
resultados son similares a los obtenidos en experiencias de control a lazo abierto en laboratorio
sobre el escurrimiento de cilindro con Re = 235 [18].

Captulo 4.6. Sistema de Control a Lazo Cerrado 100


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.12: RMS de las fluctuaciones (STD) de la velocidad en X a lo largo de la ordenada que atraviesa los
valores maximos en los escenario con y sin actuacion. Los valores guardan correspondencia con las lneas marcadas
en Figs. 4.6.10 y 4.6.11.

4.6.3. Pruebas de Robustez


Se realizan distintas simulaciones para considerar la validez del algoritmo de control fuera del
escenario de diseno. Se consideran escenarios con ruido pseudo-aleatorio agregado en la entrada
del flujo, la inyeccion de trazador y las mediciones en los sensores. En todos los casos se realizan
cambios en los codigos de simulacion para agregar el ruido calculado como el producto entre
una variable pseudo-aleatoria (con valores entre 0 y 1) y cierto porcentaje sobre la magnitud a
modificar. Luego de aplicados los cambios, se ejecutan las simulaciones y se calcula el TKE para
compararlo con el obtenido en el control original, sin el agregado del ruido.

La Fig. 4.6.13 compara el TKE obtenido con un ruido sobre el flujo de entrada de 10 % de
amplitud. En este caso se agrega el ruido a la condicion de contorno correspondiente al borde
de entrada de forma uniforme.

Captulo 4.6. Sistema de Control a Lazo Cerrado 101


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.13: Valores instantaneos del TKE al agregar ruido pseudo-aleatorio con 10 % de amplitud en la velocidad
del flujo de entrada. A modo de referencia, se grafica el valor obtenido en el caso ideal y los valores medios de
ambos escenarios.

La Fig. 4.6.14 muestra el efecto de aplicar ruido al inyector del trazador pasivo con una ampli-
tud del 10 %. Nuevamente, se modifican las condiciones de contorno para variar la concentracion
inyectada en cada paso del tiempo.

Figura 4.6.14: Valores instantaneos del TKE al agregar ruido pseudo-aleatorio con 10 % de amplitud sobre la
concentracion de la inyeccion de trazador pasivo. A modo de referencia, se grafica el valor obtenido en el caso
ideal y los valores medios de ambos escenarios.

La Fig. 4.6.15 expone los resultados de aplicar ruido de amplitud 0,1 % en las mediciones
obtenidas de los sensores. Para ello se modifica el sistema de control y se introduce un com-
ponente pseudo-aleatorio luego del parseo de los archivos con muestras. En todos los casos, el
comportamiento del sistema de control fue satisfactorio verificandose su robustez y manteniendo
el porcentaje de reduccion del TKE del escenario ideal.

Captulo 4.6. Sistema de Control a Lazo Cerrado 102


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.15: Valores instantaneos del TKE al agregar ruido pseudo-aleatorio con 0,1 % de amplitud sobre la
concentracion medida en los sensores. A modo de referencia, se grafica el valor obtenido en el caso ideal y los
valores medios de ambos escenarios.

Del mismo modo, se consideran alteraciones en la velocidad de entrada que implican cambios
de hasta un 20 % en el numero de Reynolds. Para este proposito se vara el valor de la velocidad
de entrada utilizando una rampa hasta alcanzar el nuevo valor. Luego de cierta cantidad de
iteraciones de simulacion, se reestablece el valor original con una nueva rampa. La Fig. 4.6.17
plantea un cambio descendente de la velocidad hasta alcanzar el valor de Re = 219 (represen-
tando una variacion del 7 % respecto del valor original de Re = 235). La Fig. 4.6.16 presenta un
cambio ascendente hasta un valor de Re = 282 (variacion del 20 % respecto del original).

Figura 4.6.16: Respuesta del sistema de control frente a cambios de Re = 235 a Re = 219. Se modifican las
condiciones de entrada hasta obtener el nuevo valor. Luego de varios ciclos de simulacion se retorna a la condicion
original. Sup.: Concentracion del escalar medida en el sensor 1 y valor de referencia con el Re de simulacion para
cada instante de tiempo. Inf.: Amplitud del actuador calculado por el sistema.

Captulo 4.6. Sistema de Control a Lazo Cerrado 103


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.17: Respuesta del sistema de control frente a cambios de Re = 235 a Re = 282. Se modifican las
condiciones de entrada hasta obtener el nuevo valor. Luego de varios ciclos de simulacion se retorna a la condicion
original. Sup.: Concentracion del escalar medida en el sensor 1 y valor de referencia con el Re de simulacion para
cada instante de tiempo. Inf.: Amplitud del actuador calculado por el sistema.

En ambos casos, el sistema de control se adapta y estabiliza la estela del cilindro para
las nuevas condiciones. Las flexibilidad del controlador se demuestra en cambios no solo de la
amplitud del controlador sino en la frecuencia de control que se ve claramente afectada. Luego de
un perodo transitorio tanto en las rampas positivas como en las negativas, el sistema de control
se muestra capaz adaptar las predicciones sobre el modelo y calcular una actuacion optima para
el nuevo escenario.
Los valores de TKE obtenidos en al modificar el numero de Reynolds son comparados con
simulaciones a iguales Re pero sin actuacion (Fig. 4.6.18). En ambos casos se obtienen impor-
tantes disminuciones en el TKE, obteniendo una reduccion de aproximadamente un 80 % con
Re = 219 y 73 % con Re = 282.

Captulo 4.6. Sistema de Control a Lazo Cerrado 104


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 4.6.18: Valores instantaneos del TKE obtenidos en el sistema controlado luego de modificar el numero de
Reynolds a Re = 219 y Re = 282. A modo de referencia, se grafica el valor medio correspondiente al caso no
controlado con dichos numeros. El eje temporal guarda correlacion con las simulaciones graficadas en Figs. 4.6.17
y 4.6.16.

Captulo 4.6. Sistema de Control a Lazo Cerrado 105


4.7 Conclusiones

Durante el presente captulo fue definida la malla utilizada al simular la experiencia en


Code Saturne as como las variables numericas requeridas. Luego de obtener los resultados de la
simulacion, se verifica satisfactoriamente la frecuencia caracterstica esperada para la experiencia
(St = 0,1884) y la existencia de desprendimiento de vortices segun el regimen definido para
Re = 235.
Se presenta luego el sistema de control en C++ y el modelo de comunicacion con el simulador
escrito en Fortran. El sistema permite el control a lazo abierto que es utilizado con la actuacion
de un pulso a modo de fase de entrenamiento. Se procede con la identificacion del sistema
sobre los resultados de la fase de entrenamiento para obtener un modelo ARX que represente
al sistema. El modelo ARX es validado mediante simulaciones a control a lazo abierto con
distintas frecuencias de actuacion. En todos los casos se obtiene una respuesta aceptable de las
predicciones, sin un ajuste preciso pero respetando las frecuencias y comportamiento cualitativo
verificado en las simulaciones. En el caso de actuaciones con frecuencia de 193 % respecto de la
frecuencia caracterstica, se detectaron componente de alta frecuencia en las predicciones que no
son agregados de forma directa por la actuacion. Se presume que dichas diferencias provienen
de la saturacion de la dinamica del flujo producto de las no-linealidades que el modelo ARX no
contempla.
En la fase de control a lazo cerrado, se utiliza el modelo ARX para calcular la actuacion opti-
ma frente a cada paso de tiempo. Se desarrolla el algoritmo de control y se ajustan los parametros
para obtener un control apropiado de la experiencia. Los resultados arrojados demuestran que
los patrones de lneas de mision se circunscriben al tunel de sensores, estabilizando las con-
diciones de la estela del cilindro. El analisis de frecuencia sobre los resultados demuestra que
las frecuencias naturales de la experiencia persisten, atenuadas, luego de activado el controla-
dor. Como agregado, se detecta cierto caracter oscilatorio en la actuacion cuya frecuencia es
trasladada a la dinamica del sistema y, por lo tanto, a los valores medidos de escalar.
Se practica entonces un analisis sobre la energa cinetica y las fluctuaciones de la estela
para verificar la bondad del controlador desarrollado. Para ello la estructura de malla irregular
utilizada para la simulacion es convertida en una grilla cartesiana que permite la manipulacion
de variables fsicas. Esta transformacion posibilita el analisis sobre la Energa Cinetica de la
Turbulencia (TKE) que demuestra una reduccion de aproximadamente un 85 % respecto de
la energa del caso sin actuacion. De la misma forma, se verifica la dispersion de los valores
de velocidad demostrando que el RMS de las fluctuaciones fue reducido. Mas aun, fue posible
comprobar de forma cualitativa y cuantitativa que la zona con mayor dispersion se concentra en
torno del eje X, dentro del tunel de sensores.
Por ultimo, la robustez del controlador fue puesta a prueba frente al agregado de ruido
pseudo-aleatorio en distintos puntos de la experiencia. En todos los casos, el controlador res-
pondio de forma estable y el TKE resultante se mantuvo dentro de los rangos del escenario de
control original. Asimismo, se aplico el sistema de control en escenarios con variaciones en el Re
respecto del valor de diseno (Re = 235) consiguiendo buenos resultados en todos los casos. En

106
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

los mismos se observa la estabilizacion de la estela y reduccion del TKE en comparacion con el
caso sin actuacion (reduccion aproximada de un 80 % con Re = 219 y 73 % con Re = 282).

Captulo 4.7. Conclusiones 107


Parte 5

Conclusiones Generales y
Perspectivas

108
5.1 Conclusiones Generales

Se desarrollo un sistema de control lineal de flujos a lazo cerrado basado en el analisis visual
sobre las lneas de emision de un flujo. El controlador se basa en la modelizacion del flujo
mediante modelos de caja negra y la optimizacion de un objetivo de control utilizando tecnicas
predictivas. Se utiliza un modelo lineal ARX para describir la dinamica del sistema a controlar
y se aplica un algoritmo de GPC para calcular la actuacion optima a cada paso de tiempo con
una ley de control lineal.
El sistema fue implementado y puesto a prueba mediante simulaciones numericas que de-
mostraron su efectividad y robustez frente a variaciones en las condiciones de entrada. Como
experiencia prototipo para los ensayos se eligio el escurrimiento de un cilindro por tratarse de
un fenomeno de oscilaciones auto-sostenidas, sistemas conocidos por la existencia de fuertes
no-linealidades.
El controlador estabilizo la estela del cilindro basandose en la medicion de trazadores pasivos
en 8 sensores colocados aguas abajo y utilizando actuadores de plasma simetricos para agregar
cantidad de movimiento tangencial al cilindro. Esta configuracion demostro una reduccion de la
energa cinetica de las fluctuaciones (TKE) de mas de un 80 %. Esta verificacion emprica muestra
la validez del controlador lineal bajo escenarios adversos, donde los esfuerzos y recientes avances
cientficos son orientados al uso de estructuras no-lineales de mayor complejidad.
De esta manera se obtiene un importante avance con implicancias en el area del control de
fluidos en tiempo real, donde la simpleza y su caracter generico juegan roles fundamentales para
conseguir una performance adecuada y la factibilidad tecnica de su construccion.

El armado de la experiencia numerica, implementacion de los algoritmos, construccion del


sistema de control y verificacion de los resultados obtenidos implico un alto contenido de pro-
gramacion y habilidades en distintos lenguajes/tecnologas.
El uso de Matlab para la implementar los algoritmos de identificacion y control permitio re-
ducir la cantidad de operaciones necesarias y reutilizar construcciones existentes ampliamente
probadas. De esta forma, se intento minimizar la existencia de errores en las primeras implemen-
taciones de los algoritmos que, en una etapa temprana de la experiencia, carecan de resultados
previos que permitieran su constrastacion.
Como agregado, sus caractersticas de lenguaje utilitario y de scripting, resultaron claves
para operaciones de pre y post-procesamiento del mallado. Entre ellos se encuentra la extension
del mallado 2D generado con GID a uno 3D en un formato aceptado por el simulador Code
Saturne, la conversion de la malla irregular en una grilla regular para el computo del TKE y
RMS de las fluctuaciones junto con diversas actividades de verificacion de resultados.
Respecto del sistema de control, la eleccion de C++ demostro ser acertada pudiendo integrar
las distintas partes bajo un aplicativo robusto. La flexibilidad del lenguaje y gran soporte para la
integracion quedo expuesta al comunicar el sistema Fortran del simulador y las implementaciones
de los algoritmos en Matlab. A su vez, su empleo facilito la inclusion experimental de tecnicas

109
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

de GPGPU mediante CUDA C/C++ para optimizar los tiempos de identificacion del sistema,
factor clave para permitir el uso del sistema de control en una experiencia real de laboratorio.
Otro paso importante en este sentido, consiste en la compatibilidad que ofrece C++ en la
interaccion con dispositivos perifericos como ser camaras digitales o generadores de senales. En
este sentido, se realizaron pequenos sistemas experimentales para la obtencion de imagenes que
podran integrarse facilmente en el controlador y reemplazar el uso del simulador.

Tanto el diseno de los algoritmos de identificacion del sistema y de control como la defini-
cion de la experiencia prototipo, la preparacion de la simulacion numerica y la verificacion de
resultados, representaron un enorme desafo de trabajo interdisciplinario. La coordinacion de
esfuerzos dentro de un equipo de trabajo con areas de conocimiento tales como la matematica,
fsica, fluidodinamica y teora de control resulta ardua, pero es a su vez un trabajo desafiante
y fructfero. Es importante remarcar el papel que juega la informatica en este contexto, don-
de se requiere la cristalizacion de distintas concepciones teoricas en una experiencia de ciencia
aplicada. La correcta simulacion, comunicacion entre sistemas nuevos o existentes, algoritmia
aplicada, analisis de tiempos o capacidades de computo resultan factores fundamentales para
garantizar el exito de estas lneas de investigacion.

Captulo 5.1. Conclusiones Generales 110


5.2 Trabajos Futuros

El presente trabajo establece una base importante para el desarrollo de distintos proyectos
de control a lazo cerrado de fluidos.
Quiza las mayores perspectivas del sistema de control desarrollado consisten en su implemen-
tacion en una experiencia real de laboratorio. Con este objetivo en consideracion se desarrollo un
programa externo al simulador y que pudiera conectarse facilmente con dispositivos de labora-
torio como camaras o generadores de senales. A su vez, los pequenos avances experimentales
sobre el uso de GPGPU con CUDA C/C++ marcan el camino de evolucion del sistema para
responder frente a las exigencias de velocidad y previsibilidad de un sistema en tiempo real.
La eleccion de ARX como modelo matematico fue componente importante del sistema cons-
truido. Este modelo, sin embargo, no contempla la existencia de ruido en las senales. Una
variacion de modelos auto-regresivos que contempla dicho comportamiento puede encontrarse
en modelos ARMAX. La extension del sistema de control en este sentido podra significar un
paso importante para garantizar la robustez del control frente a condiciones reales.
Otro factor que resulta de gran interes consiste en el uso de una cantidad mayor de sensores
visuales. La modificacion de posiciones, sensibilidad y cantidad de los sensores demostro tener
un efecto directo sobre los parametros de tuning del controlador. Sin embargo, la extension del
campo de vision del algoritmo GPC podra asegurar la estabilidad en una zona mas amplia del
fluido. El empleo entonces de una cantidad mayor de sensores permitira un mejor modelo de la
realidad y la posibilidad de estabilizar experiencias que no cuenten con relaciones de simetra
como la del escurrimiento bajo estudio.
En caso de mantener la disposicion de sensores, es necesario evaluar el efecto de retardo que
poseen frente a cambios en la actuacion. El retardo puede ser modelado mediante parametros que
permitan modificar la posicion de los sensores sin que esto afecte la sensibilidad del controlador.
Aun utilizando un controlador predictivo, existe la posibilidad de experimentar con distintas
leyes de control para el modelo identificado. Se conocen referencias a sistemas de control adapta-
tivos que fueron implementados experimentalmente para el presente trabajo. Si bien es necesario
mejorar la velocidad de convergencia, simulaciones preliminares (Apendice D.1) demostraron re-
sultados prometedores con actuaciones mas suaves y sin oscilaciones no deseadas. Por otra parte,
el aumento del orden del modelo y horizontes de prediccion con el controlador original mejora su
actuacion eliminando las altas frecuencias pero mantiene el caracter oscilatorio (Apendice D.2).
Por ultimo, se puede destacar la posibilidad de realizar un producto comercial o academico
que emplee el sistema desarrollado para simular experiencias. Aunque el exito comercial del
producto esta relacionado con la eficacia del sistema en una experiencia real aun no practicada,
el alto grado de interconexion y el caracter generico de los algoritmos permitiran un gran abanico
de combinaciones entre experiencias prototipo, parametros de control y modelos matematicos.

111
Apendices

112
A Resena de Control de Fluidos

A.1. Objetivos
Los objetivos generales para el control de fluidos suelen estar vinculados a reducciones en
el costo de recursos necesarios para cierto proceso, facilitar o impedir cierto fenomeno. Estos
objetivos macro se apoyan en otros mas especficos que definen las particularidades del control
a aplicar sobre el flujo bajo estudio. Para ilustrar esta diferencia se puede mencionar la ma-
nipulacion de fuselajes de avion para aumentar la sustentacion, reducir el arrastre y demorar
la transicion entre fluidos turbulento y laminar. Estos objetivos basicos no excluyentes tienen
como finalidad mejorar las condiciones de vuelo: reduccion de ruidos o vibraciones, reduccion del
combustible requerido para vencer la resistencia al aire, entre otras. Muchos de los estudios del
area se concentran en los objetivos especficos para, una vez dominados, poder contribuir a un
objetivo de mayor envergadura. A continuacion se resumen los objetivos especficos de control
de fluidos que resultan mas relevantes [22]:

Arrastre (drag ): El efecto de arrastre esta relacionado con la resistencia al avance de cierto
cuerpo sobre un fluido. Esta vinculado con la friccion que produce el fluido en movimiento
contra las superficies del cuerpo y con la creacion de vortices o cambios de presion que
dependen de la forma del cuerpo en cuestion.

Sustentacion (lift): Es la fuerza perpendicular al flujo del fluido que actua en sentido contrario
al peso del objeto en movimiento. En aeronautica, se aplican esfuerzos continuos a la
busqueda de escenarios con mayor sustentacion sobre superficies alares para permitir ganar
altura a la aeronave. Por el contrario, en automovilismo, se realizan cambios en el fuselaje
como el agregado de alerones que disminuyen la sustentacion y empujan el vehculo hacia
el suelo.

Separacion de la Capa Lmite (separation): Este fenomeno se observa al aparecer una va-
riacion de la velocidad del fluido demasiado grande como para que el fluido se pueda adherir
al solido. Al ocurrir esto, las lneas de corriente alrededor del cuerpo se separan generando
desprendimientos en forma de vortices o turbulencia que aumentan la resistencia al movi-
miento. Por estos motivos se pretende posponer la separacion de la capa lmite salvo en
situaciones donde una separacion temprana facilite la mezcla de ciertos fluidos.

Repegado de la Capa Lmite (reattachment): Al ocurrir la separacion de la capa lmite,


las lneas de corriente proximas al cuerpo son deflectadas y se forma una estela. Depen-
diendo de las caractersticas de la experiencia, las lneas de corriente pueden converger
y adherirse nuevamente formando una burbuja entre el punto de separacion y de read-
herencia. Este fenomeno involucra ademas una zona de recirculacion de fluido que queda
confinada al espacio de la burbuja y resulta deseable por la reduccion de los efectos nega-
tivos de la estela.

113
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Retardo en Transicion (transition delay ): La transicion en el regimen del fluido denota la


zona donde el fluido deja de comportarse de forma laminar para adoptar caractersticas
turbulentas. En el primer caso se pueden identificar capas paralelas definidas por las lneas
de corriente. El flujo es ordenado y no ocurre mezcla entre las distintas capas. Por el
contrario, en regimen turbulento, el movimiento del fluido es caotico y se intensifica el
intercambio de materia entre las distintas capas. Dependiendo de los fines del control, la
transicion temprana puede ser beneficiosa para facilitar cierta mezcla de materia aunque
en la mayora de los casos se opta por retardar su efecto debido al costo energetico asociado
con la aparicion de un flujo turbulento.

A.2. Evolucion Historica


A lo largo de los anos, el control de fluidos ha presentado una evolucion constante marcada
por etapas. Los primeros estados son definidos por una fase emprica de tecnicas e instrumentos
que finaliza con los primeros estudios de L. Prandtl (1975-1953) que en 1904 introduce la teora
de la capa lmite e inicia la era cientfica del control de fluidos. Durante esta etapa se obtuvieron
avances teoricos importantes en dispositivos de control mediante la aplicacion de conceptos
fsicos y principios racionales en contraposicion a la prueba y error que proliferaba en la era
anterior. Ya comenzada la Segunda Guerra Mundial y durante la carrera armamentista de las
decadas subsiguientes (perodo 1940-1970), el ritmo de progreso acelerado fue marcado por las
necesidades militares en los campos de balstica, aeroespacial y naval, entre otros. Fue la crisis
energetica de 1973 la que da inicio a una nueva era regida en esta oportunidad por el sector civil.
Las necesidades de reduccion de costos en procesos industriales o transporte aereo, terrestre y
naval implicaron grandes inversiones de agencias gubernamentales y privadas en investigacion
de control de fluidos. Por ultimo, la decada de 1990 da inicio a una nueva etapa que continua a
la actualidad donde los avances alcanzados tanto en fluidodinamica como en teora de control,
computacion, sistemas fsicos y electronicos amplan los horizontes del control de fluidos. En este
contexto se incrementa la complejidad de las practicas y prepondera el uso de control reactivo
por la versatilidad que posee [22].
Ademas del avance en tecnicas especficas, las necesidades economicas suelen dirigir los esfuer-
zos cientficos de este sector de forma directa o indirecta. A modo de ejemplo de las implicancias
economicas que pueden causar los avances en control de fluidos, se estima que una reduccion del
1 % en el consumo mundial de combustible aeronautico por aplicaciones de control implicara
1,25 millones de dolares diarios de ahorro en costos directos (valores estimado al ano 2002) y
reducira considerablemente el impacto ambiental de ese tipo de transporte [17].
Aun cuando existe un progreso continuo en la tecnologa y metodos aplicados para el control
de fluidos, persisten ciertas diferencias entre teora, resultados simulados y aplicaciones reales.
Esta circunstancia da origen a la frase El Arte del Control de Fluidos, refiriendose a la mezcla
de innovacion y experiencia con los que se llevan a cabo muchos de los ensayos que permiten el
progreso de la disciplina [17].

Apendice A. Resena de Control de Fluidos 114


B Mallado de la Experiencia

B.1. Detalle del Mallado


La Fig. B.1 muestra un histograma acumulativo de las cantidades de celdas utilizadas de
acuerdo a la superficie que presentan. Se puede observar la cantidad de elementos triangulares
utilizados dependiendo del volumen ocupado por los mismos con un incremento importante en
aquellos que presentan un tamano cercano a 0,1, es decir, con superficie aproximada de 0,005.

Figura B.1: Histograma acumulativo sobre las cantidades de celdas. Si bien se muestra el volumen de las celdas
como clasificador para la acumulacion, se aclara que el mallado fue realizado 2D donde se asume una profundidad
unitaria para el calculo volumetrico.

El total de celdas triangulares utilizadas en la malla es de 169507. El detalle de la configu-


racion puede observarse en las Fig. B.2 y B.3.

115
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura B.2: Tamano en la separacion del mallado para las lneas de la geometra. El mallado en las lneas de
frontera se define con un tamano mayor (0,1) al utilizado en las lneas que determinan el cilindro (0,03). A fines
de proveer una transicion suave, es necesario agregar lneas ficticias que fijen separaciones intermedias (0,04 y
0,06).

Apendice B. Mallado de la Experiencia 116


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura B.3: Tamano en la separacion del mallado para las superficies de la geometra. El sistema de mallado utiliza
los tamanos definidos en las superficies para generar las celdas intermedias a las distintas lneas del mallado. Las
dimensiones de las celdas varan gradualmente entre los tamanos definidos por las lneas y los indicados por las
superficies encerradas entre ellas.

B.2. Efectos de Cambios Bruscos en la Malla durante la Simu-


lacion
Las Fig. B.4, B.5 y B.6 muestran una secuencia de simulacion donde la existencia de cambios
bruscos en las dimensiones de las celdas del mallado generan errores de calculo localizados. Estos
errores se propagan rapidamente a traves de las celdas vecinas generando la divergencia de la
simulacion.

Apendice B. Mallado de la Experiencia 117


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura B.4: Magnitud de la velocidad en una simulacion divergente. Un sector del mallado presenta celdas que no
cumplen con las condiciones de estabilidad en la cercana del cilindro.

Figura B.5: Magnitud de la velocidad en una simulacion divergente. Las celdas afectadas comienzan a trasladar
sus valores elevados a celdas vecinas.

Figura B.6: Magnitud de la velocidad en una simulacion divergente. El error de calculo se expande afectando a
un porcentaje elevado de las celdas en la simulacion, se torna inestable y eventualmente diverge.

Apendice B. Mallado de la Experiencia 118


C Verificacion de la Identificacion del Sis-
tema

C.1. Ajuste en Implementacion Matlab


El criterio utilizado para definir el orden del modelo ARX para el algoritmo de control
consiste en verificar el nivel de ajuste que poseen las predicciones del modelo respecto de las
muestras utilizadas para generarlo. Si bien se conocen rutinas pre-existentes en Matlab tanto para
la identificacion del sistema (llamada arx ) como para realizar una comparacion visual sobre el
grado de ajuste del modelo calculado (llamada compare), se decide realizar una implementacion
propia de cada uno. En el primer caso, se pretende comprobar la efectividad del algoritmo
definido y la posibilidad de una implementacion que soporte alto paralelismo en CUDA C/C++.
En el segundo caso se requiere control sobre los resultados del ajuste de cada variable, mientras
que la rutina existente tiene una clara orientacion a la comparacion visual.
El codigo fuente del desarrollo propio de la identificacion del sistema (lfd arx.m) y de la
comparacion sobre el porcentaje de ajuste que posee lfd compare.m pueden encontrarse en el
Apendice F.5. El algoritmo de comparacion utiliza la funcion predict de Matlab para predecir
los valores yi (k) futuros segun el modelo ARX utilizando un horizonte de prediccion s para cada
paso de tiempo.
A continuacion se presentan los resultados del ajuste calculado para distintos ordenes del
modelo (p) incluyendo la media del porcentaje de ajuste de todas las variables yi , as como los
valores mnimo y maximo obtenidos. Como horizonte de prediccion se utiliza el valor aproximado
de medio perodo natural, s = 43 . Se utiliza la simulacion de entrenamiento de 1090 muestras
con la actuacion de un pulso.

Ajuste Matlab Ajuste Ajuste Ajuste


Orden (p) Prom. [ %] Prom. [ %] Mn. [ %] Max. [ %]
20 83,39 83.39 62.21 90.21
30 91,28 91.31 83.09 95.35
40 96,54 96.53 95.51 97.93
50 98,08 98.08 97.21 99.16
60 98,78 98.78 98.05 99.35
70 99,32 99.32 98.96 99.59
80 99,57 99.57 99.27 99.70
90 99,70 99.70 99.44 99.82
100 99,75 99.73 99.36 99.94

C.2. Ajuste y Tiempos en Implementacion C++


A continuacion se resumen las pruebas de concepto realizadas sobre el desarrollo del algoritmo
de identificacion del sistema en Matlab en comparacion su version en C++.

119
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Dado que se requieren operaciones de algebra lineal para resolver multiplicaciones, descom-
posiciones e inversiones, se decide evaluar el uso de libreras Basic Linear Algebra Subprograms
(BLAS) existentes. A tal fin, se utiliza la librera GNU Scientific Library (GSL) y GPU Accele-
rated Linear Algebra (CULA) siendo la primera una implementacion pura en C++ y la segunda
una version BLAS que da soporte a rutinas CUDA. A fin de comparar la velocidad de las im-
plementaciones, se crea una abstraccion de matriz utilizando el tipo de dato abstracto de GSL
pero con implementaciones de las operaciones con ambas libreras.
El conjunto de datos utilizados coincide con la la fase de entrenamiento del sistema con la
actuacion de un pulso y N = 1090 muestras. En cada caso, se realizo un promedio sobre los
valores obtenidos de dos ejecuciones. Se mide el tiempo de ejecucion total y el ajuste de cada
coordenada del vector de estado obteniendo un ajuste promedio de todas las coordenadas, la
coordenada de ajuste mnimo y la de ajuste maximo. Se utiliza aproximadamente un perodo
caracterstico del fenomeno como horizonte de prediccion, s = 90, para realizar la comparacion
con lfd compare.m (ver Apendice F.5).
Se emplea un equipo con procesador Intel i5 2500K con 4 cores y una velocidad de reloj de
3,3Ghz y una placa grafica nVidia GeForce GTX 570 con 480 CUDA cores y una velocidad de
GPU de 1,57Ghz.

Tiempo Ajuste Ajuste Ajuste


Orden (p) Lenguaje [s] Prom. [ %] Mn. [ %] Max. [ %]
10 Matlab 1,7 57,0 50,4 67,7
10 C++ (CUDA/CULA) 1,5 56,9 50,5 67,6
10 C++ (GSL) 55,5 56,9 50,5 67,6
20 Matlab 13,6 61,6 49,1 72,7
20 C++ (CUDA/CULA) 3,4 61,4 48,7 72,8
20 C++ (GSL) 330,1 61,4 48,7 72,8
40 Matlab 118,9 88,0 66,8 93,6
40 C++ (CUDA/CULA) 12,4 87,9 66,8 93,6
40 C++ (GSL) 1952,1 87,9 66,8 93,6
50 Matlab 229,3 90,4 67,2 95,9
50 C++ (CUDA/CULA) 19,0 90,4 67,2 95,9
50 C++ (GSL) 3497,9 90,4 67,2 95,9
60 Matlab 403,9 91,6 67,4 97,8
60 C++ (CUDA/CULA) 28,0 91,6 67,4 97,8
60 C++ (GSL) 5746,2 91,6 67,4 97,8
70 Matlab 646,7 92,2 67,4 99,0
70 C++ (CUDA/CULA) 40,7 92,2 67,4 99,0
70 C++ (GSL) 8614,6 92,2 67,4 99,0
80 Matlab 951,7 92,4 67,4 99,4
80 C++ (CUDA/CULA) 53,5 92,4 67,4 99,4
80 C++ (GSL) 12317,8 92,4 67,4 99,4
90 Matlab 1349,6 92,5 67,4 99,6
90 C++ (CUDA/CULA) 70,2 92,5 67,4 99,6
90 C++ (GSL) 16957,2 92,5 67,4 99,6

Se observa un incremento importante del tiempo de ejecucion a medida que se aumenta p


para todos los sistemas. Sin embargo, la version que utiliza capacidades de GPGPU resulta
sensiblemente mas rapida resolviendo el caso de identificacion de sistema utilizado en el sistema
de control (p = 90) en tiempos cercanos al minuto mientras el codigo Matlab utiliza aproxi-
madamente 22 minutos. Por otra parte, la implementacion del sistema en GSL demostro un
rendimiento muy pobre con ordenes de magnitud de diferencia en cuanto a los tiempos de eje-
cucion para todo p.

Apendice C. Verificacion de la Identificacion del Sistema 120


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Cabe destacar que el nivel de ajuste se mantiene similar en todos los casos.

Apendice C. Verificacion de la Identificacion del Sistema 121


D Avances Experimentales para Trabajos
Futuros

D.1. Control Adaptativo


Se realizaron pruebas experimentales sobre leyes de control adaptativo. En este esquema, la
matriz de control se adapta a cada paso de simulacion en base a ajustes evaluados contra la
funcion objetivo. En el escenario ideal, la matriz de control converge hacia valores optimos de
control. Las experiencias realizadas (Fig. D.1) muestran un posible escenario de convergencia
donde el actuador se acerca asintoticamente a su optimo.
Aunque posee resultados prometedores, este tipo de controlador presenta grandes complica-
ciones en cuanto al tuning de parametros debido a la combinacion de varias variables sobre el
peso del control. Otro factor importante consiste en la necesidad de realizar largas simulaciones
hasta contar con la suficiente informacion para determinar la convergencia o no de la actuacion
(Fig. D.2). El codigo fuente utilizado en este esquema de pruebas fue basado en [36] y se puede
encontrar en el Apendice G.3.

Figura D.1: Control Adaptativo aplicado sobre el escurrimiento del cilindro. Se puede apreciar el caracter asintotico
de la senal de actuacion.

122
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura D.2: Comparacion de control adaptativo con distintos parametros de ajuste. Se puede observar gran
diferencia en los resultados de control frente a cambios en los parametros, pudiendo divergir (lnea azul) o mantener
una progresion asintotica (lnea verde) con cambios menores en las variable de ajuste.

D.2. Control con Modelo ARX de Orden Elevado


Con el objetivo de comprobar el efecto de modificaciones drasticas en el orden del modelo
ARX sobre el sistema controlador, se realizaron distintas pruebas experimentales con un nuevo
mallado. En este caso, se definio una malla fina en el centro pero con celdas de mayor tamano en
la periferia. De esta forma se obtuvo una menor cantidad total de celdas que permitio extender
el mallado aguas abajo de la experiencia para mejorar la resolucion numerica. Las Figs. D.3 y
D.4 muestran el detalle del mallado.

Figura D.3: Tamano en la separacion del nuevo mallado para las lneas de la geometra.

Apendice D. Avances Experimentales para Trabajos Futuros 123


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura D.4: Tamano en la separacion del nuevo mallado para las superficies de la geometra.

Luego, se empleo el sistema de control bajo estudio cuyo codigo fuente se encuentra en el
Apendice F.6 ampliando el valor del orden del modelo, p. Los primeros resultados no fueron
positivos pero se pudo observar una mejora notable al realizar un muestreo mas lento sobre los
valores de simulacion (practicando under-sampling). En este caso se obtuvo una senal de control
mucho mas suave que en las experiencias originales, que controla los valores de escalar sin el
agregado de fluctuaciones ni senales de alta frecuencia indeseables (Fig. D.5).
A fin de ajustar los parametros de control con el nuevo orden del modelo, fue necesario
modificar los pesos de los sensores. El resumen de los parametros de control se puede observar
en la Tabla D.1.

Parametro Variable Valor


Orden del Modelo p 150
Paso de Tiempo Simulacion t 0,061
0.122 (1 muestra
Paso de Tiempo Muestreo cada 2 pasos de Sim.)
Peso de Sensores Sup. q1 , q2 , q3 , q4 1,1 0,75 0,5 0,25
Peso de Sensores Inf. q5 , q6 , q7 , q8 1,1 0,75 0,5 0,25
Costo del Controlador 0,00045

Tabla D.1: Valores definidos para los distintos parametros de control del sistema.

Apendice D. Avances Experimentales para Trabajos Futuros 124


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura D.5: Experiencia de control realizada sobre una nueva malla utilizando ordenes de modelo ARX elevados.
En este caso, utilizando p = 150, se consigue un control estable luego de reducir la frecuencia de muestreo a la
mitad de la empleada en el control original.

D.3. Captura de Imagenes Mediante Camaras Digitales


Se realizaron trabajos experimentales con las distintas camaras digitales del Laboratorio de
Fluidodinamica de la Facultad de Ingeniera (UBA), donde se realizo el proyecto de investigacion.
En todos los casos se intento medir los tiempos de respuesta de las camaras para tomar y
transferir imagenes a un posible sistema controlador. Se adjuntan los resultados obtenidos que

Apendice D. Avances Experimentales para Trabajos Futuros 125


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

pueden ser de utilidad en futuras implementaciones de la experiencia en tiempo real. La Tabla


D.2 incluye el detalle de las propiedades de cada camara evaluada. Los codigos fuente utilizados
se encuentran en el Apendice G.1.

Crop/
Nombre Resol. Max. FPS ROI Buffer Tipo de Transferencia
PixelFly qe - Cooke Coroporation 640x480 50 Si Sin buffer Directa por RJ45 en placa Adq.
SpeedCam Mini Vis e2 - Weinberger 512x512 2500 Si 2GB buffer Desde buffer por Ethernet 1Gbit
TM9701 - Pulnix 768x484 30 No Sin buffer Directa por placa Adq. PXD

Tabla D.2: Caractersticas de camaras digitales evaluadas para la adquisicion de imagenes en futuros escenarios
de control en tiempo real.

D.3.1. PixelFly qe
Se escribe el codigo de captura usando la API provista por PixelFly y se miden los tiempos
aproximados. En este caso se cuenta con un SDK unificado para las PixelFly y las camaras de
la familia Sensicam llamado Uniform SDK. Dicha librera posee una interfaz clara y requiere
elementos de WinApi siendo por demas portable. Los resultados obtenidos se resumen segun:

Imagenes Capturadas 200


FPS 50
Tiempo Total 4000ms
Tiempo Promedio 20ms. Equivalente a 50 FPS (tiempo de transferencia despreciable).

D.3.2. Pulnix
Se trata de una camara anticuada con una API de control del adaptador provista por la
empresa Imagenation. Se posee documentacion de la API y se realiza un sistema que retorna los
siguientes resultados:

Imagenes Capturadas 120


FPS 30
Tiempo Total 4000ms
Tiempo Promedio 33, 3ms. Equivalente a 30 FPS (tiempo de transferencia despreciable).

D.3.3. SpeedCam Mini Vis e2


La SpeedCam no posee una API de acceso programatico. Tampoco permite sacar fotogramas
de forma unitaria, solo es posible sacar una rafaga que es almacenada en el buffer interno de la
camara y luego transmitido a la PC.
La camara posee codigo hecho en Java del cual se pueden obtener los .jar para emplearlos en
un codigo de prueba. Se consulta al soporte de fabrica sobre manuales o informacion de utilidad
para utilizar las libreras sin mayores resultados.
Luego de realizar distintos trabajos de re-ingeniera mediante la decompilacion del sistema
que utiliza la camara, se elabora un codigo que permite obtener las siguientes mediciones:

Imagenes Capturadas 200


FPS 2500
Tiempo Total 7800ms (unicamente de transferencia)
Tiempo Promedio 39ms. Equivalente a 25 FPS.

Apendice D. Avances Experimentales para Trabajos Futuros 126


E Publicaciones

E.1. Anales de la AFA


Publicacion presentada durante el mes de Diciembre de 2012 en los Anales de la Asociacion
Fsica Argentina (AFA) bajo el ttulo Control a Lazo Cerrado de la Estela de un Cilindro en
coautora con Thomas Duriez, Ada Cammilleri y Guillermo Artana.

E.2. Physics of Fluids


Publicacion presentada durante el mes de Septiembre de 2013 en la revista Physics of Fluids
de la American Institute of Physics bajo el ttulo A visualization-based flow control system
en coautora con Thomas Duriez, Ada Cammilleri, Lionel Mathelin y Guillermo Artana.

127
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

CONTROL A LAZO CERRADO DE LA ESTELA DE UN CILINDRO

CYLINDER WAKE CLOSED-LOOP CONTROL SYSTEM


Pablo Roca, Thomas Duriez, Ada Cammilleri, Guillermo Artana

Laboratorio de Fluidodinmica, Facultad de Ingeniera, Universidad de Buenos Aires


cada@fi.uba.ar

Recibido: 13/12/2012; aceptado: 14/03/2013


Se introduce un sistema de control a lazo cerrado sobre el escurrimiento de un cilindro basado en el
procesamiento de imgenes. Dentro de una simulacin numrica directa, se considera el flujo que contornea un
cilindro y se procura disminuir las fluctuaciones en su estela. Trazadores pasivos son inyectados en el sistema
para construir un modelo matemtico de identificacin de sistema tipo ARX con su concentracin medida en
ciertos puntos de las imgenes. Luego, mediante el empleo de un algoritmo de control GPC, se acta inyectando
cantidad de movimiento tangencial al cilindro para forzar el flujo y reducir las fluctuaciones de la estela.
Palabras clave: cilindro, estela, simulacin, imgenes, control, lazo cerrado, ARX, GPC.
A closed-loop control system is introduced to stabilize a cylinder wake based on image processing. A direct
numerical simulation is used to compute the fluid flow through a cylinder and stabilize its wake. Passive scalar
tracers are injected in the system to constitute an AutoRegressive with eXogenous input (ARX) mathematical
model by sensing its concentration on certain image sectors. A Generalized Predictive Controller (GPC)
algorithm is used to calculate the necessary actuation to stabilize the wake by adding momentum tangentially to
the cylinder wall.
Keywords: cylinder, wake, simulation, images, control, closed-loop, ARX, GPC.

base a mediciones para retroalimentar al sistema de


I. INTRODUCCIN
control y poder ajustar los parmetros en tiempo real. Se
Es conocida la importancia que reviste la disciplina trata de un control activo con la capacidad de adaptar
de control de fluidos tanto para el mbito cientfico los parmetros de control y la energa utilizada en base a
como para la industria. A los objetivos clsicos de teora los resultados medidos en el sistema, el objetivo
de control como el seguimiento de valores de referencia, definido y la modelizacin matemtica que se realiz
rechazo de perturbaciones y de errores de medicin se sobre el sistema.
suman aplicaciones especficas como la reduccin de Es en este contexto donde la modelizacin del
fuerzas de arrastre o la supresin de inestabilidades que sistema fsico recubre un carcter fundamental para
resultan de gran valor por sus aplicaciones prcticas. estimar la actuacin a aplicar en busca de un objetivo
El estudio de control de fluidos se caracteriza por definido. Algunas estrategias implican el uso de
buscar las partes sensibles de un flujo que permitan ecuaciones fundamentales de la mecnica como es el
obtener modificaciones que lleven el flujo a un estado caso de las ecuaciones de Navier-Stokes que son
deseado en base a pequeas perturbaciones linealizadas para construir un modelo de orden reducido
intencionales conocidas como actuacin. Un sistema de que permita estimar el flujo8. Otros modelos se
control se puede caracterizar por el esquema de concentran en propiedades globales como el consumo
actuacin empleado segn sea pasivo, activo o reactivo. de energa para realizar control por bsqueda de
El control pasivo consiste en realizar modificaciones extremos9 donde se busca un mnimo a la funcin global
en el entorno de operacin de forma de parametrizar de costo determinada por el estudio de un control activo
ciertos cambios respecto de la modificacin que se forzado (lazo abierto). Finalmente existen los modelos
observa en el flujo. En este esquema, una vez empricos de caja negra basados en la observacin del
establecido el entorno no es posible cambiar la sistema en un proceso de control a lazo abierto. Un
parametrizacin. Ejemplos tpicos son generadores de ejemplo de este escenario consta en la identificacin de
vrtices1,2,3 y pequeos objetos fsicos dentro de la sistemas basados en modelos AutoRegressive (AR) que
estela del fluido4. En control activo se aplica energa determinan una relacin entre el estado del sistema
durante la actuacin para adaptar la respuesta del fluido actual y el medido en tiempos pasados. En el pasado se
a un resultado deseado. En este caso, las condiciones de realizaron experiencias de control basadas en modelos
la experiencia pueden cambiar a lo largo del tiempo autoregresivos ARX10,11,12,13 y autoregresivos
siendo necesario adaptar los parmetros de actuacin ARMAX 14
que permiten utilizar algoritmos de
definidos. Ejemplos tpicos son controles tipo jet prediccin y optimizacin sobre ciertas funciones
(pulsados o sintticos)5,6, dispositivos mecnicos definidas como objetivo para el control.
ajustables y cilindros rotantes7. El control reactivo El presente trabajo desarrolla un sistema de control
implica que el estado del flujo es medido o estimado en de fluidos reactivo basado en el procesamiento de

ANALES AFA Vol. 23 FLUIDOS (29-33) BUENOS AIRES 2012 29

Apendice E. Publicaciones 128


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

imgenes para obtener un modelo a caja negra ARX que


permita describir y predecir el sistema fsico. Se elige el
experimento prototpico del escurrimiento sobre un
cilindro a fin de efectuar las pruebas correspondientes
sobre el algoritmo y bloques de control.
II. MODELO FSICO SIMULADO
Como modelo fsico bajo estudio se toma el
escurrimiento del fluido sobre un cilindro y se plantea el
objetivo de estabilizar su estela. Filamentos de escalar Figura 3. Vorticidad computada en la simulacin luego de
alcanzar el estado estacionario (Re:235).
pasivo son inyectados aguas arriba del experimento para
medir luego la concentracin en ciertos puntos y definir
un vector de estado del sistema con dichos valores. Se
colocan dos actuadores en la pared del cilindro con el
objetivo de agregar cantidad de movimiento de forma
tangencial para forzar el flujo y controlar la estela. Se
simula una actuacin del tipo plasma15 con inyeccin de
cantidad de movimiento a travs de un mecanismo de
impacto inico. La accin es homognea, simultnea y
simtrica a lo largo de dos semiarcos de 5% de
Figura 4. Concentracin de escalar medida en el sensor 1
circunferencia del cilindro, en una posicin cercana al
durante la fase de inicio de inicio del sistema. Al llegar al
punto de separacin. (Fig. 1) rgimen estacionario se puede apreciar la periodicidad en la
concentracin con un T aproximado de 90 pasos de
simulacin (Re:235).

III. IDENTIFICACIN DEL SISTEMA


Para representar la dinmica del escurrimiento
elegimos considerar un modelo lineal en tiempo discreto
dado por

(1)
Figura 1. Esquema del experimento. Ubicacin de actuadores
y sensores de concentracin del escalar durante la simulacin donde y(k) es un vector de m x 1 que representa el
2D (Re:235, dt:0.061, cilindro centrado verticalmente a 7.5 estado del sistema (la salida), u(k) es un vector de r x 1
dimetros de la entrada sobre una superficie de 27.5 x 25 que representa la actuacin (la entrada), p es el orden
dimetros. del modelo, k es el paso del tiempo. En el caso que
estudiamos y(k) es un vector que contiene la medida
Con este diseo la actuacin procura posponer la instantnea de concentracin del trazador en las
separacin de la capa lmite. distintas posiciones de los sensores y u(k) representa la
Luego de mallar la geometra del sistema en 2D, se amplitud instantnea de los actuadores.
utiliza el aplicativo Cdigo Saturne para realizar Nos referimos al sistema definido por (1) como un
simulaciones de elementos finitos. modelo Modelo autoregresivo con entrada exgena
En cada paso de la simulacin se mide la (ARX). Los coeficientes matriciales del modelo,
concentracin de un escalar pasivo que se inyecta con para 1 i p, para 0 i p , de m x m y m x r
flujo constante aguas arriba del cilindro. Los puntos de respectivamente, son llamados parmetros de Markov
sensado se ubican de manera simtrica en direccin del del observador y caracterizan al modelo10.
escurrimiento dentro de la estela formada por el cilindro Definiendo el vector de parmetros
(Fig. 2, 3 y 4).

y el vector de regresin

Figura 2. Concentracin de escalar computada en la


simulacin luego de alcanzar el estado estacionario (Re:235). la Ec. 1 pueda ser escrita de la forma

30 ANALES AFA Vol. 23 FLUIDOS (29-33) BUENOS AIRES 2012

Apendice E. Publicaciones 129


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

siendo conocidos como


A fin de estimar , se define una fase de parmetros de Markov del sistema10, y es una matriz
entrenamiento donde la actuacin es forzada mientras se de ms x sr definida por una serie de relaciones
mide la respuesta del sistema fsico. Luego, se utilizan recursivas a partir de los parmetros del modelo.
las N muestras de entrenamiento junto al criterio de Se establece un algoritmo de control basado en el
estimacin por cuadrados mnimos para determinar un algoritmo Generalizado de control predictivo (GPC)11
estimador de segn con el objetivo de disminuir la concentracin de escalar
medida en los sensores.
Se determina entonces la funcin de costo apropiada
para describir la ley de control

donde es una matriz de sm x sm, diagonal en


bloques , tales que y
Dado que la matriz puede estar
mal condicionada consideramos un mtodo ms efectivo representa el peso del sensor i, .
para estimar los parmetros16. Suponiendo una ley de control lineal, y utilizando el
mtodo de Lagrange, la minimizacin del funcional
Si se define un vector de definido en la Ec. 4 sujeto a cumplir la Ec. 3 da como
que reune a todos los resultado
coeficientes de la matrices y , la Ec. 1 puede
tambin ser escrita de la forma
donde I representa a la matriz identidad de sr x sr.
Dado que se requiere el valor de actuacin para el
paso de tiempo actual (k), es posible ahorrar tiempo de
Luego, la estimacin de se obtiene a partir de la
cmputo determinando las primeras r filas del producto
descomposicin QR de la matriz donde es de del primer trmino de la Ec. 5 segn
Nm x d e Y es de Nm x 1 tales que

Una vez aplicada la actuacin y obtenidas las


mediciones del paso de tiempo siguiente, se cierra el
lazo de control calculando e ingresando nuevamente
IV. ALGORITMO DE CONTROL A LAZO en la Ec. 6. La secuencia del sistema de control queda
CERRADO descripta en el Algortimo 1.
Siendo s el horizonte de prediccin definimos de
sr x 1, de sm x 1 y de p(m+r) x 1 segn ALGORITMO 1: ALGORITMO DE CONTROL PROPUESTO

Entrada: p: orden del modelo, s: horizonte de prediccin,


: costo del actuador
Salida: Control del sistema en estudio
1: Medir valores del ciclo de entrenamiento
2: Obtener el modelo ARX de orden p
3: Definir el controlador con s, y el modelo ARX
4: Para cada Paso de tiempo k hacer
5: Medir los valores y para el paso k
6: Construir agregando los valores de y(k)
De la Ec. 1 podemos obtener una ecuacin matricial 7: Utilizar Ec. 6. para obtener u(k)
que predice las futuras salidas del sistema10 8: Aplicar la actuacin u(k)
9: Fin para

donde es una matriz Toeplitz dada por V. RESULTADOS DEL SISTEMA DE CONTROL
A fin de identificar el modelo del sistema, se idea
una fase de entrenamiento donde la actuacin es forzada
con la seal caracterstica de un pulso para medir su
respuesta frente a una amplia variedad de frecuencias de
entrada. Los valores medidos son utilizados en la Ec. 2
para formar los coeficientes de control en base al
modelo estimado (Fig. 5).

ANALES AFA Vol. 23 FLUIDOS (29-33) BUENOS AIRES 2012 31

Apendice E. Publicaciones 130


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figura 8. Vorticidad resultante de la simulacin del control


Figura 5. Fase de entrenamiento del sistema. Luego de en el instante de mnima concentracin medida en los
aplicar el pulso de actuacin, el valor de concentracin sensores (Re:235).
medido en las lneas de sensores se reduce abruptamente
producto de la estabilizacin de la estela.
Luego de realizada la calibracin de los distintos VI. CONCLUSIONES
parmetros de control, se simula el sistema fsico con el Se desarroll un sistema de control a lazo cerrado en
controlador ya entrenado obteniendo una actuacin de una simulacin numrica. Se verific su correcto
control que estabiliza la estela del cilindro (Fig. 6, 7 y funcionamiento con la experiencia prototpica del
8). escurrimiento del cilindro. La estela del cilindro fue
De la misma forma se pudo verificar la sensada a travs de la medicin de la concentracin del
adaptabilidad del algoritmo frente a condiciones fuera escalar inyectado y estabilizada gracias a la actuacin de
de diseo. A tal fin se modific la velocidad del flujo de respuesta. El sistema de control definido resulta lo
entrada de forma temporal observando la capacidad del suficientemente genrico para ser adaptado a otros
control para encontrar un nuevo punto de actuacin experimentos e implementado con un esquema de
ptima. Luego de cierto perodo de transicin, el captura de imgenes.
sistema cambia su seal de control y logra estabilizar la
estela (Fig. 9).

Figura 9. Cambios en la condicin de entrada. El sistema de


control adapta la respuesta de su actuador para estabilizar la
Figura 6. Lazo cerrado de control. La actuacin se estela del cilindro bajo el cambio de las condiciones de
incrementa cuando el escalar medido crece y se reduce entrada indicadas por la referencia.
cuando su efecto estabiliza la estela y baja la concentracin
de escala en los sensores. Queda pendiente para trabajos futuros el estudio de
mtodos adaptativos de control12 y sus resultados con el
esquema propuesto.
Asimismo, procuraremos estudiar el incremento de
la cantidad de sensores utilizados, la medicin de los
tiempos de cmputo requeridos, el anlisis del
desempeo con posibles optimizaciones del algoritmo y
la implementacin de la experiencia en laboratorio.
VI. REFERENCIAS
1- Lin J. Progress in Aerospace Sciences, 38(4-5), 389420
(2002).
Figura 7. Vorticidad resultante de la simulacin del control 2- Godard G. and Stanislas M. Aerospace Science and
en el instante de mxima concentracin medida en los Technology, 10(6), 455464 (2006).
sensores. En este momento, la actuacin comienza a crecer 3- Duriez T., Aider J., and Wesfreid J. Physical Review
para compensar las oscilaciones en la estela (Re:235). Letters, 103(14) (2009).
4- Cadot O., Thiria B., and Beaudoin J. Solid Mechanics and
its Applications, 14, 529537 (2009).
5- Godard G. and Stanislas M. Aerospace Science and
Technology, 10(6), 455464 (2006).
6- Kostas J., Foucaut J., and Stanislas M. Flow, Turbulence
and Combustion, 78(3-4), 331363 (2007).

32 ANALES AFA Vol. 23 FLUIDOS (29-33) BUENOS AIRES 2012

Apendice E. Publicaciones 131


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

7- Thiria B., Goujon-Durand S., and Wesfreid J. Journal of 12- Kegerise M.A., Cambell R.H., and Cattafesta L.N. Journal
Fluid Mechanics, 560, 123147 (2006). of Sound and Vibration, 307, 924940 (2007).
8- Protas B. and Styczek A. Physics of Fluids, 14(7), 2073 13- Huang S.C. and Kim J. Physics of Fluids, 20(101509)
2087 (2002). (2008).
9- Beaudoin J.F., Cadot O., Aider J.L., and Wesfreid J.E. 14- Herv A., Denis Sipp P.J.S., and Samuelides M. Journal of
Physics of Fluids, 18(085107) (2006). Fluid Mechanics, 702, 2658 (2012).
10- Juang J.N. and Phan M. Deadbit predictive controllers. 15- DAdamo J., Gonzlez L.M., Gronskis A., and Artana G.
Technical Memorandum 112862, Nasa (1997). Fluid Dynamics Research, 44(055501), 20 (2012).
11- Kegerise M.A., Cambell R.H., and Cattafesta L.N. Journal 16- Ljung L. System Identification: Theory for the User.
of Sound and Vibration, 307, 906923 (2007). Prentice-Hall Inc., Englewood Cliffs, N.J. (1987)

ANALES AFA Vol. 23 FLUIDOS (29-33) BUENOS AIRES 2012 33

Apendice E. Publicaciones 132


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

A visualization-based flow control system


Pablo Roca,1 Thomas Duriez,1 Ada Cammilleri,1 Lionel Mathelin,2 and Guillermo Artana3, a)
1)
Laboratorio de Fluidodinmica, Facultad de Ingeniera, Universidad de Buenos Aires,
Argentina
2)
LIMSI, CNRS, Orsay, France
3)
CONICET, Laboratorio de Fluidodinmica, Facultad de Ingeniera, Universidad de Buenos Aires,
Argentina
(Dated: October 24, 2013)
A closed-loop control system is introduced to stabilize a cylinder wake flow based on images of streaklines.
Passive scalar tracers are injected upstream the cylinder and their concentration is monitored downstream
at certain image sectors of the wake. An AutoRegressive with eXogenous inputs (ARX) mathematical model
is built from these images and a Generalized Predictive Controller (GPC) algorithm is used to compute
the actuation required to stabilize the wake by adding momentum tangentially to the cylinder wall through
plasma actuators. The methodology is demonstrated on a numerical simulation and the provided results show
that good performances are achieved.

PACS numbers: 47.85.L

I. INTRODUCTION

Control of fluid flows is a discipline with a remarkable importance for industry and science. Classical control
objectives such as reference value tracking or disturbances rejection can be applied to many configurations, including
drag reduction or instability suppression that are of great interest for practical applications.
On one hand, passive control devices aim at controlling the flow state with a given target without requiring an
external power source to operate. In this type of control, the action is permanent and is not suitable for a change in
the control parameter since they are strongly tight to the original layout of the experiment. This methodology can
be found for instance in vortex generators,13 or splitter plates,4 . On the other hand, active control requires applying
energy for the flow to attain a defined target. This kind of control allows changing the actuation parameters in time
to adjust the controller to new conditions in the experiment. Typical examples of actuators involved with this control
are pulsed and synthetic jets,2,5 , adjustable mechanical devices, rotating cylinders,6 or plasma actuators,79 . These
devices are most commonly used in an open-loop control configuration which does not involve feedback mechanisms
at time scales comparable to characteristic times of the flow nor prediction of the future state of the actuated flow.
Closed-loop control is a signal-based control that involves the estimation or measurement of the instantaneous state
of the flow to feed the controller back and adjust the control parameters in real time. This configuration thus involves
evaluation of the actuators inputs from the sensor outputs to achieve a desired effect. This kind of control is suitable
for applications with limited amount of energy to manipulate the flow and for systems intended to a relatively wide
operating envelope, thereby limiting the drop in performance associated with multiple designs.
Inferring a model describing the system, and capable of predicting the response of the flow to the forcing, from
observations is crucial to compute the necessary actuation for a given target. There basically exist two strategies
to obtain models that attempt to arrange observations into some pattern: the physics-based model approach and
the system identification approach. The former seeks a reduced order model (ROM) based on a basis deduced from
experiments. One of the usual choices of basis has been to consider a Proper Orthogonal Decomposition (POD). The
set of equations of the reduced order model is obtained by a Galerkin projection of the Navier-Stokes equation onto
the POD modes. This procedure leads to a system of ordinary differential equations of as many equations as modes
retained in the analysis. However, neglecting the high index modes usually responsible for damping of the physical
system may lead to a divergence of the resulting ROM. A description of efforts to avoid this effect can be found for
instance in10 , among others. POD modes usually exhibit multiple frequencies and it is difficult to associate their
spatial structure to an easily observable flow feature. Further, the approximation basis obtained may not be versatile
enough to accurately describe diverse flow conditions. Recently, different efforts have been dedicated to improve the
quality of the basis to remedy this limitation,11 . Another limitation of this POD-based approach is the difficulty with
the proper inclusion of an external action in the formulation, either associated to the actuation or to autonomous
disturbances to the flow.

a) Electronic mail: gartana@fi.uba.ar

Apendice E. Publicaciones 133


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Among the advantages of this formulation is the possibility to easily define the objective function. When it is
desired to minimize fluctuations of the flow, it is possible to directly seek for a minimization of the total energy of
the fluctuating part of the flow, which can be determined from the temporal coefficients of the modes (chronos). It is
also possible to build a ROM from the so-called global modes, but this strategy is not always well suited,12 . However,
one of the most restrictive requirements of ROM approaches is that the data used to generate the model are velocity
fields of the flow to be controlled. From the point of view of field applications, this constitutes a major limitation.
Hence, the analysis with this kind of approach has been mostly restricted to numerical benchmarks or experiments
in wind tunnels equipped with Particle Image Velocimetry (PIV) systems.
Models issued from the second approach, System Identification, are usually empirical black box models. One of
the most popular choices of this methodology is based on an autoregressive relation between current and past system
control variables and observables that constitute the state vector. Typical examples are the algorithms based on
AutoRegressions with eXogenous inputs (ARX),1316 or AutoRegressions with eXogenous inputs and Moving Average
(ARMAX),17 . Estimation of the parameters of the model is performed using known input-output data retrieved from
flow field measurements. The estimation involves minimizing the error norm (typically in the L2 -sense) between the
model output and the actual output from the fluid flow system given the same input data sequence. Shortcomings
associated with a system identification strategy such as that described in17 comprise effects associated to non-linearities
not included in the analysis, a laborious tuning of the parameters of the model and difficulties in the definition of the
objective function.
In this work we propose an improvement upon this last point. Actuation is introduced with the purpose of forcing
some characteristic streaklines of the flow to lie into a prescribed region. The objective function to be minimized is
defined in terms of the concentration of a tracer injected upstream in the flow, at selected points downstream. To
this end, we introduce a new visualization-based approach for active fluid flow control.
This approach has similarities with the concept of visual servoing techniques. Control strategies based on vision
are well established techniques in robotics and automation communities. The method consists in using feedback
information provided by a vision sensor observing the system to be controlled. In the field of flow control, only a few
efforts have been carried-out along these lines, using the velocity flow fields as input data1820 .
In practical applications, the techniques of flow control based on velocity field data often prove impractical. The use
of Particle Image Velocimetry (PIV) systems outside of a laboratory environment may present some problems related
to the use of powerful lasers, to the dense seeding of tracers required and to the careful alignment of sophisticated
cameras. Further, traditional PIV systems may not be rapid enough for all applications as a consequence of low
sampling rates and time required for the processing of the acquired images.

A. Scope of the paper

To avoid difficulties associated with the use of PIV, we here present a closed-loop control methodology simply
based on the image intensity in a set of probes (selected points of the image of the flow field). The image intensity
is proportional to the local concentration of a passive tracer injected upstream. The prototypical wake produced by
a cylinder immersed in a uniform stream is chosen as the physical system to control. The flow is controlled with
plasma actuators disposed on the cylinder surface. The present work is focused on a laminar, two-dimensional flow
at a low Reynolds number (Re, evaluated with the cylinder diameter, free stream velocity and viscosity coefficient)
of 235. This value is close to the threshold of appearance of 3-D instabilities of the non-actuated flow. However, a
synchronized plasma actuation in the span-wise direction, enlarges the range of Reynolds number in which the flow
remains 2-D and a steady plasma actuation has already been shown to be able to stabilize this kind of flow,21 . We
here test the visualization-based control on a numerical benchmark since all system variables are then easily available
and this facilitates the evaluation of the control performance. However, the present method can be easily applied in
a laboratory environment and beyond in a real application.
In section 2 of this manuscript we explain how data were generated using a numerical simulation. The system
identification algorithm is presented in section 3. In section 4, we propose a Generalized Predictive Controller (GPC)
scheme to minimize fluctuations of the wake over a predictive horizon. In section 5, the control system is tested and
results are discussed. Model validity and robustness under noise in the measurements, in the tracer injection system,
and changes in the inflow conditions are analysed.

II. PSEUDO-EXPERIMENTAL SET-UP

We consider a two-dimensional flow around a circular cylinder and the control objective of stabilizing the wake
(suppression of the vortex shedding).

Apendice E. Publicaciones 134


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Simulations are performed with the code Saturne,22 . A uniform stream with constant velocity is considered as inlet
condition, and the other boundary conditions are indicated on Fig. 1. The Strouhal number of the flow (calculated
from the shedding frequency, free-stream velocity and diameter of cylinder) is close to 0.2. Considering the mesh
used and the CFL condition, the non-dimensional time step of the simulation (based on velocity of the free-stream
and cylinder diameter) was set to 0.061. A filament of a passive scalar with a unit constant concentration is injected
upstream the cylinder. The concentration of the injected scalar is monitored downstream and a control action is
applied at each simulation step. Several probes are symmetrically placed in the wake along the streamwise direction
to measure the scalar concentration (see Figs. 2 and 3). Once the non-actuated flow system attains the asymptotic
regime, the tracers concentration at each probe becomes periodic in time (Fig. 4). Note that in a physical experiment,
the tracers concentration at a given point can be associated to the instantaneous gray level of a pixel, or group of
pixels, in a single camera snapshot. Unless specified, we consider a perfect tracer injection system, perfect sensors and
a spatially uniform, constant in time, velocity at the inlet. In a practical implementation, there can exist fluctuations
of the injection system and the cameras used to visualize the flow have errors in the measurements. We will take
into account these effects in the closed loop problem by considering a pseudo-random noise introduced in the scalar
concentration at the injection point and a pseudo-random noise affecting measurements of the sensors. In some cases,
we will also admit that a pseudo-random noise may affect the inlet conditions and that the inlet velocity is altered
in time. Two actuators are set on the cylinder surface and add momentum tangentially to the surface. The set-up of
the simulation considers plasma actuators,23 with simultaneous and equal momentum injection over an arc length of
about 5% of the cylinder circumference (Fig. 1). The actuators are located close to the separation line with the goal
that the momentum injection produced by actuation promotes the postponement of the separation of the boundary
layer from cylinder surface. Previous studies have shown that, with this actuator configuration, a steady forcing of
amplitude high enough is able to stabilize the wake flow,21 . We here propose to stabilize the wake flow with a time
varying forcing of much lower amplitude. The actuator is simulated as in21 and24 as an imposed boundary condition
in a localized region of the surface of the cylinder. We identify the amplitude of actuation with the value of the
tangential velocity at that location at the surface of the cylinder. The control system we propose builds upon the two
actuators- that force the flow simultaneously, in phase, and with the same amplitude- and upon the measurements
obtained from eight probes. The system identification algorithm that we describe in the following section enables to
derive a model that links the amplitude of the actuation and the value of scalar concentration at each probe. The
control algorithm we consider in this work determines the command required at each time step based on the previous
values of the amplitude of actuation, on the scalar concentration at the probes measured in the past and on the future
measurements predicted by the model within a time horizon. Consequently, the controller scheme can be classified as
a multiple input multiple output (MIMO) configuration.

Figure 1. Experiment layout. Actuators and scalar concentration probes location (Re = 235, Simulation domain 27.5 25
diameters, cylinder vertically centred at 7.5 diameters from the inlet).

III. SYSTEM IDENTIFICATION

To describe the flow dynamics we consider a linear time-invariant model given by

y(k) + 1 y(k 1) + + p y(k p) = 0 u(k) + 1 u(k 1) + + p u(k p) (1)

Apendice E. Publicaciones 135


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figure 2. Instantaneous streakline pattern of the non actuated flow and values of scalar concentration at the different probes.

Figure 3. Instantaneous vorticity field of the non actuated flow and vorticity amplitude at probes location.

Figure 4. Time evolution of scalar concentration measured at probes 1 and 4 when starting the simulation. Note the difference
in amplitude and the delays in time between the two measures associated to the different positions of the probes.

Apendice E. Publicaciones 136


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

where y(k) Rm is the system state (the output), u(k) Rr the actuation (the input), p N the model order and
k N the current time step.
We refer to this system as an AutoRegressive with eXogenous inputs model (ARX). The model matrix coefficients,
i , 1 i p, and i , 0 i p, of size m m and m r respectively, are the so-called observer Markov parameters
and characterize the model,13 . Sometimes the dynamics from u to y contains a delay of nd samples, so some first
coefficients i are zero. It may be a good idea in some cases to explicitly display this delay in eq. (1). However for
easier notation and taking into account that is acceptable to underestimate delays but not to overestimate them, we
directly consider in this work nd = 0.
Defining the parameters matrix
:= (1 . . . p 0 . . . p )T R(pm+(p+1)r)m
and the regression vector

y(k 1)
..

.

y(k p)
(k) =

Rpm+(p+1)r ,

u(k)
..
.
u(k p)
Eq. (1) can be written as
y(k) = T (k).
If we define as a vector of size d := pm2 + (p + 1)mr which gathers all the coefficients of matrices i and i , and
consider (k) := (k) Im , being the Kronecker product and Im the m m identity matrix, Eq. (1) rewrites as
y(k) = T (k).
To estimate , we consider a training phase where both the actuation and the response of the physical system are
known. N training samples are used, together with a least squares criterion, to determine an estimation N
LS
of from

!1
1 X 1 X
N N
LS
N = (k)T (k) (k)y(k). (2)
N N
k=1 k=1
PN
When the matrix k=1 (k)T (k) is close to being singular, a more effective method may be used to estimate the
25
parameters, . Defining
T := ((1) . . . (N )) RdN m ,
Y T := (y T (1) . . . y T (N )) R1N m ,
the estimation of is obtained from a QR decomposition of the N m (d + 1) matrix [Y ], in which the first d
columns are those of the matrix and the last column is the vector Y .
2
With these definitions, our problem consists in finding which minimizes kY k2 . We consider a QR- 
R0
decomposition of matrix [Y ] = QR, Q being a N m N m matrix with orthonormal columns and R =
0
 
R1 R2
a N m (d + 1) upper triangular matrix. In particular, R0 = with R1 a d d upper triangular matrix, R2
0 R3
a d 1 vector, and R3 a scalar. 2
2
Q having orthonormal columns, it comes that kY k2 = QT (Y ) 2 . Since QT is the first d columns of
R and QT Y is thelast column of R, it yields
R1 R2
QT = and QT Y = .
0 R3
 
2 R2 R1 2
So, we obtain QT (Y ) 2 =
. When minimizing this quantity and solving the system R1 =

R3 2
2

R2 we obtain the estimation of . Also note that Y = |R3 |2 .
2

Apendice E. Publicaciones 137


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

A. Tuning of parameters

The training phase was designed to collect input-output instances (Fig. 5) and identify a model of the system.
During this phase, the actuators trigger a step pulse and the scalar measurements are used in Eq. (2) to estimate
the coefficients. Considering the flow as a nonlinear dynamical systems, this forcing step perturbs the orbit in the
state space from the attractor. The system then enters a relaxation phase in which the trajectory gradually returns
to the orbit around the attractor. Analysis of these transients has been carried-out in some recent works,26 . When
the pulse step is triggered, the scalar concentration in the probes is drastically reduced during a short period of time.
This reduction occurs with different delays that depend on the distance of the probe to the cylinder. The number of
samples to be considered to train the autoregression model is related to these delays and to the time required for the
system to relax to an unperturbed flow dynamics when actuation ceases17 .

Figure 5. Training phase of the system. The four upper plots show the scalar concentration evolution in time at the different
probes during the training period. The bottom plot shows the pulsed actuation applied simultaneously to each actuator.

The variables involved in the system identification strategy are the pulse duration of the forcing, the number N of
training samples, the sampling rate, the number of probes m and their location and the horizon of autoregression p.
In our configuration, the tuning parameters have been set to p = 90 time steps, N = 1090, pulse duration of 10 time
steps and a non-dimensional sampling rate of 0.061.

Apendice E. Publicaciones 138


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

B. Effects of non-linearities

A review of cylinder wake control with single sensor linear feedback control systems or systems involving several
pressure probes can be found in27 . Wake flows can be considered in general as oscillators exhibiting self-excited
oscillations. Although the von Krmn mode is the first global mode to become unsteady, a wake flow far above the
critical Reynolds number, for which the steady flow becomes unstable, may exhibit multiple interacting global modes.
Stabilization of the flow requires in principle attenuation of all these global modes. Single-sensor control is difficult
since forcing with an amplitude high enough to suppress the most unstable mode often destabilizes other modes.
Measurements at different locations within the wake are therefore not simply related by a phase shift and multiple,
spatially distributed, sensors are then required to control the flow. The present visualization-based approach is hence
well suited to stabilize a large number of modes since many sensors are available.
To account for the effect of non-linearities, a natural choice would probably have been to use a non-linear model,25 .
However, this approach is computationally more challenging and expected benefits are often limited. Discussions
about linear control approaches in non-linear flows can be found for example in16 . In particular, a strategy based
on neural networks has been proposed for a wake flow control problem in a recent work,28 . Other strategies like
adaptive identification algorithms or the stabilization of the flow prior to system identification are also possible,29 . In
agreement with the rationale of other researchers,16 , for flow control purpose, instead of deriving an accurate system
model, our primary goal is to construct a simple input-output data-based system model, which could lead to effective
feedback control laws.
When non-linear interactions between the global modes and the control input are significant, a linearised model
developed with the purpose of reducing kinetic energy fluctuation of the flow manages to suppress oscillations of the
signal at the sensor locations,30,31 . Therefore, even when non-linearities are present, the use of a linear model allows
to locally reduce the quantity to be minimized. We thus aim at deriving a model, not to control the dynamics of all
oscillating modes, but to control the dynamics of some streaklines. It hence reformulates from annihilating all unstable
modes to stabilizing solely the modes that significantly drift the flow from its prescribed pattern. It reduces to a
wake design problem in which only wake fluctuations within prescribed margins determined by the probes location are
allowed. Obviously, a physical knowledge of the flow pattern that can be associated to a stabilized flow is required.
In the case of the cylinder wake, it is well known that stabilization produces narrow and longer wakes. Hence, by
forcing the wake to exhibit this pattern one can expect that the energy associated to the fluctuations will be reduced.
To test the validity of the model, we compare tracers concentration signals, in conditions different from those of
the training phase, with the outputs of the identified model (90 time step ahead prediction) yi , i = 1, , 8. We test
the model with a data set, labelled data series 1, associated to a step actuation combined with a sinus function (sinus
frequency is 225 % higher than the natural frequency of the flow), Fig. 6. We can observe a satisfactory behaviour
of the model reproducing the main frequencies of the oscillations and not dramatically straying from data (Fig. 8).
The system is stable and returns to its equilibrium state once the actuation ceases. However, during the actuation
interval, the model predicts signals of tracer concentration with a high frequency component while the actual system
does not exhibit these frequencies. This can be related to saturations of the flow dynamics induced by non-linearities
that are absent in the identified linear model we consider.
A second data series (data series 2 ) considers the case when the period of the forcing allows lock-in (Fig. 7).
The frequency of the excitation considered is here 1.25 times higher than the frequency of the natural flow and the
actuation imposes its dynamics to the vortex shedding. For this data set, the identified model reproduces the signals
at the probes correctly without introducing significant spurious frequencies (Fig. 9).

IV. CLOSED-LOOP CONTROL ALGORITHM

Letting s N be the prediction horizon, we define vectors ys Rsm , us Rsr and vp Rp(m+r) according to


y(k) u(k)

ys (k) := .. ..
. , us (k) := . ,
y(k + s 1) u(k + s 1),

Apendice E. Publicaciones 139


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figure 6. Model behaviour with data series 1. In the upper plots are shown the scalar concentration evolution in time at
different probes during the experiment. The bottom plot shows the actuation applied simultaneously to each actuator. The
actuation is a step combined with a sinus function having a frequency of 225 % higher than the natural frequency of the flow.


y(k 1)
..

.

y(k p)
vp (k p) :=
u(k 1) .

..
.
u(k p)

From Eq. (1) we can obtain a matrix expression to predict future outputs of the system,

ys (k) = T us (k) + vp (k p) (3)

where T is a Toeplitz matrix given by

Apendice E. Publicaciones 140


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Figure 7. Model behaviour with data series 2 in a lock-in regime. In the upper plots are shown the predictions of the
identified model for the scalar concentration evolution in time at different probes. The bottom plot shows the actuation applied
simultaneously to each actuator. Actuation is a sinus function with a frequency 125 % higher than the natural frequency of
the flow.


0
0(1) 0
(2) (1)

T :=
0 0 0

... ... ... ... ...
(s1) (1)
0 . . . . . . 0 0

(1) (s1)
with 0 , 0 , . . . 0 known as system Markov parameters, and T and matrices of size ms sr and ms p(m + r)
respectively. They are obtained by a series of recursive relations from the model parameters as described in13 .
(k)
The so-called pulse response parameters of the system 0 are obtained from:

Apendice E. Publicaciones 141


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

10

Figure 8. Comparison of spectrograms of the simulation (left) and predictions of the model built through system identification
(right) for the data set of Fig. 6.

Figure 9. Comparison of spectrograms of the simulation (left) and predictions of the model built through system identification
(right) for the data set of Fig. 7.

(0)
0 = 0 ,
k
X
(k) (ki)
0 = k + i 0 , 1 k p,
i=1
p
X
(k) (ki)
0 = i 0 , k > p.
i=1

The matrix is defined as



1 2 . . . p 1 2 . . . p
(1) (1)
2 . . . p
(1)
1
(1) (1)
2 . . . p
(1)
:=
...
1
... ... ... ... ... ... ...
(s1) (s1) (s1) (s1)
1 ... . . . p 1 ... . . . p

with the following relations for 1k , kj and kj :

Apendice E. Publicaciones 142


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

11

(0)
1 = 1 ,
k
X
(k) (ki)
1 = k+1 + i 1 , 1 k p 1,
i=1
k
X
(k) (ki)
1 = i 1 , k p,
i=1
(j) (j1) (j1)
1 = 1 1 + 2 ,
..
.
(j) (j1)
p1 = 1 p1 + p(j1) ,
(j1)
p(j) = 1 p ,
(j) (j1) (j1)
1 = 1 1 + 2
,
..
.
(j) (j1)
p1 = 1 p1 + p(j1) ,
(j1)
p(j) = 1 p .

We consider a control algorithm based on Generalized Predictive Controller (GPC),14 , with the objective of de-
creasing the scalar concentration measured by the sensors. The algorithm generates, at each sampling instant, the
future s inputs that minimize the cost function
J = ysT (k)Qys (k) + uTs (k)us (k) (4)
where Q is a sm sm block diagonal matrix with blocks Qi := diag(q1 . . . qm ), with qi the weight of sensor i,
0 qi 1. The values of these weights are set to unity. The use of different weight values for each probe i allows,
for instance, to take into account the downstream diffusion of the vorticity of the tracer. An improved version of this
cost function with vectors ys ranging from k + nd to k + s 1 , gives the possibility to take into account the delays
from inputs to outputs. However, for the sake of simplicity, we consider in this manuscript nd = 0 .
The parameter of Eq. (4) penalizes the actuation magnitude. In our experiments, has always been set to 4.
Note that minimizing the cost function J does not necessary imply minimizing the kinetic energy of fluctuations.
This goal is achieved only by a suitable choice of probes location. The minimization of the cost function only allows
to penalize certain, undesirable, streaklines.
We consider a linear control law, us (k) = Kvp (k p), with K a sr p(m + r) matrix containing the controller
coefficients.
Applying Lagranges method to minimize J under the constraint given by Eq. (3), we consider the Lagrangian
L = J + hl, ys T us vp i, where l Rsm denotes the Lagrange multiplier, and h, i is a suitable inner product of
Rsm , yielding the system of optimality:

ys T us vp = 0,
2Qys + l = 0,
2us T T l = 0.
One then obtains K = (T T QT + Isr )1 T T Q, hence
us (k) = (T T QT + Isr )1 T T Qvp (k p) (5)
where Isr represents the sr sr identity matrix.
a. Since only the actuation value for the current time step k is required, only the first r rows of the product in
the first term of Eq. (5) are considered, so that finally
u(k) = {(T T QT + Isr )1 }r T T Qvp (k p). (6)
Once the actuation u is computed from Eq. (6) and the measurements y are taken, vp is updated and the whole
process is repeated at the next time step. The resulting control algorithm is now summarized:

Apendice E. Publicaciones 143


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

12

Algorithm 1 Proposed control algorithm.


Require: p: model order, s: prediction horizon, : actuator cost.
Ensure: Control of the system under study.
1: Take measurements during a training cycle.
2: Compute an ARX model with order p.
3: Define the controller K from s, , and the ARX model.
4: Define the initial vp from y and u values up to step k 1.
5: for all time step k do
6: Use Eq. (6) to obtain u(k).
7: Apply the computed actuation u(k).
8: Measure y(k), the resulting output for the time step k.
9: Update vp from y(k) and u(k).
10: end for

V. CONTROL SYSTEM RESULTS

Once the control parameters are tuned, the physical model is simulated and the trained controller determines an
actuation signal that stabilizes the flow.
In Fig. 10, the clear link between actuation and scalar concentration is shown. As we can see, once the actuation is
activated and after a short period of time, the control system stabilizes. A decrease (increase) of scalar concentration
detected by the sensors leads to a fast decrease (increase) of the magnitude of actuation. The instantaneous images
of streaklines (Fig. 11) and vorticity field (Fig. 12) compared to the non-actuated flow (Figs. 2 and 3) show the
stabilization of the wake as a consequence of the forcing and how the wake is controlled.
To further illustrate the stabilization of the wake, we represent in Fig. 13 the energy associated with fluctuations
as a function of time for the non-actuated and the actuated flow. As we can see, a reduction of about 85 percent in
energy is obtained.
The control impact can also be appreciated from the plot of the RMS fields of the velocity in the stream-wise
direction (Figs. 14 and 15). As can be seen, the control system forces the wake fluctuations to be concentrated within
the narrow path delimited by the probes. We show on Fig. 16 the RMS values along an horizontal line containing the
point that exhibits the maximum value of fluctuations (indicated as white lines on Figs. 14 and 15). The decrease
of the peak values of the RMS and the shift of this maximum towards downstream positions that we can observe in
Fig. 16 indicates the stabilizing effect of the control on the wake. These results are similar to those obtained with a
continuous forcing,21 .
The validity of the control algorithm under conditions different from the training configuration is now considered
with cases in which a pseudo-random noise of amplitude 10% affects the uniform inlet flow velocity (Fig. 17), a
pseudo-random noise of 10% affects the concentration injection (Fig. 18) and pseudo-random noise of 0.1% affects
sensor measurements, (Fig. 19). In all these cases the behavior of the control system was satisfactory and illustrates
its robustness.
Alteration of the inlet velocity was also considered with changes up to 20% in the Reynolds number. For this
purpose we considered a time varying velocity at the inlet following an ascending (resp. descending) ramp, plateaued
at the new value and then decreased (resp. increased) to the original one. We can observe on Figures 20 and 21
that the controller is able to adapt the command and preserve the control performance. After a transient, the control
system stabilizes the cylinder wake under the new conditions and the fluctuating energy diminishes (Fig. 22).

VI. CONCLUSIONS

A visualization-based closed-loop control system was developed and tested in a numerical simulation. The approach
we propose is based on images of the flow and essentially consists in preventing the flow field to exhibit some patterns.
A laminar flow around a circular cylinder was chosen to demonstrate the algorithm performance in reducing the wake
oscillations amplitude. The control was achieved via plasma actuators disposed on the cylinder surface that add
momentum tangentially to the cylinder surface close to the boundary layer separation line. The control system is
based on an ARX system identification model with a Generalized Predictive Controller.
The flow considered here exhibits global instabilities with amplitudes that are driven by the non-linear interaction
of the modes. Single-sensor control of this kind of flow is difficult since forcing with an amplitude high enough to
suppress the most unstable mode often destabilizes other modes. Indeed, the un-modelled non-linear dynamics may

Apendice E. Publicaciones 144


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

13

Figure 10. Closed-loop control results. Scalar concentration at different probes and amplitude of actuation as a function of
time.

severely limit the performance of control systems based on a single or very few probes. The present visualization-
based system effectively relies on a large number of non-intrusive sensors. The resulting linear controller was shown to
achieve an efficient feedback control with a reduction of more than 80% in the mean fluctuating kinetic energy. In the
context of separated flows, the control effectiveness is often limited by the absence of workable cost functions16 . In this
regard, our study represents a step forward, extending the use of linear system models in complex flows by allowing
the choice of a suitable cost function. The goal of this work was restricted to obtaining a narrow wake, which, for
this kind of flow, is known to produce a reduction of the kinetic energy associated with wake fluctuations. Extensions
to other goals usually considered in separated flows like lift enhancement or separation reduction are possible by a
suitable choice of the probes location.
Compared to noise amplifier flows, the present test case puts markedly less stringent constrains on how to take into
account the effects of external disturbances in the control strategy. The robustness of the control system was tested
by considering pseudo-random noise in the measures of the sensors, tracer injection system and uniformity of the inlet
flow. We also tested the ability of the controller to adjust to a new inlet velocity. In all these cases, and within the
range of the parameters studied, we obtained satisfactory results, achieving a reduction of the wake fluctuations energy
of about 85%. These results provide confidence in application of this approach to physical experiments that may be
close to field configurations. The number of probes required depends on the characteristics of the flow considered and
the tuning of parameters may be laborious in some cases. In physical experiments, the use of a numerical benchmark to

Apendice E. Publicaciones 145


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

14

Figure 11. Instantaneous streaklines and values of scalar concentration at the probes of the controlled wake.

Figure 12. Instantaneous vorticity field and values at the probes of the controlled flow.

Figure 13. Instantaneous and time-averaged kinetic energy of fluctuations for the non-actuated and controlled flow. Control is
activated at time step number 500.

Apendice E. Publicaciones 146


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

15

Figure 14. RMS of the velocity in the stream-wise direction for the non-controlled flow. The horizontal white line at y=0.415
is in correspondence with the maximum of the RMS.

Figure 15. RMS of the velocity in the stream-wise direction for the controlled flow. The horizontal white line at y=0.280 is in
correspondence with the maximum of the RMS.

Figure 16. RMS of the velocity in the streamwise direction along white lines indicated on figures 14 and 15.

Apendice E. Publicaciones 147


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

16

Figure 17. Instantaneous values and time averages of the kinetic energy of the controlled flow when a pseudo-random noise of
10 % is added to the inlet flow velocity.

Figure 18. Instantaneous values and time averages of the kinetic energy of the controlled flow when a pseudo-random noise of
10% is added to the injection system.

Figure 19. Instantaneous values and time averages of the kinetic energy of the controlled flow when a pseudo-random noise of
0.1 % is added to the sensors.

Apendice E. Publicaciones 148


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

17

Figure 20. Changes in the inlet condition. The Reynolds number increases from 235 to 282 and recovers its initial value following
a ramp (green-dash plot)). Upper plot: Scalar concentration at probe 1 as a function of time. Lower plot: Instantaneous
amplitude of the forcing in each actuator. The control system adapts its command to stabilize the wake to the new inlet
condition.

Figure 21. Changes in the inlet condition: The Reynolds number of the controlled flow decreases from 235 to 219 and recovers
its initial value following a ramp (green-dash plot)). Upper plot: Scalar concentration at probe 1 as a function of time. Lower
plot: Instantaneous amplitude of the forcing in each actuator. The control system adapts its command to stabilize the wake
to the new inlet condition.

determine the appropriate parameters may simplify this procedure. Compared with other control techniques relying
on images of the flow, some advantages of the present implementation are the simplicity of the instrumentation
required and a reduction of the post-processing steps of the acquired images. The proposed control methodology
is generic enough to be adapted to other experiments, in particular those involving three-dimensional flows where
the tracer concentration can be monitored with images acquired from two or more cameras suitably disposed. The
present work can be considered as a proof-of-concept and an actual application to a real-world problem may benefit
from the use of a more robust ARMAX model instead of the present ARX implementation. Mutatis mutandis, the
corresponding control methodology is quite similar.

Apendice E. Publicaciones 149


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

18

Figure 22. Instantaneous and time averages of kinetic energy fluctuations when inlet conditions change in time as in Figs. 20
and 21.

ACKNOWLEDGMENTS

We thank C. Collewet for helpful comments. This research is supported by grants of the UBA, CONICET and
CNRS.

REFERENCES

1 J. Lin, Review of research on low-profile vortex generators to control boundary-layer separation, Progress in Aerospace Sciences 38,
389420 (2002).
2 G. Godard and M. Stanislas, Control of a decelerating boundary layer. part 3: Optimization of round jets vortex generators, Aerospace

Science and Technology 10, 455464 (2006).


3 T. Duriez, J. Aider, and J. Wesfreid, Self-sustaining process through streak generation in a flat-plate boundary layer, Physical Review

Letters 103 (2009).


4 A. Roshko, On the wake and drag of bluff bodies, J. Aeronaut. Sci. 22, 124132 (1955).
5 J. Kostas, J. Foucaut, and M. Stanislas, The flow structure produced by pulsed-jet vortex generators in a turbulent boundary layer in

an adverse pressure gradient, Flow, Turbulence and Combustion 78, 331363 (2007).
6 B. Thiria, S. Goujon-Durand, and J. Wesfreid, The wake of a cylinder performing rotary oscillations, Journal of Fluid Mechanics

560, 123147 (2006).


7 G. Artana, R. Sosa, E. Moreau, and G. Touchard, Control of the near wake-flow around a circular cylinder with electrohydrodynamic

actuators, Experiments in Fluids 35, 580588 (2003).


8 M. Munska and T. Mclaughlin, Circular cylinder flow control using plasma actuators, AIAA paper 2005-0141 (2005).
9 T. Jukes and K. Choi, Control of unsteady flow separation over a circular cylinder using dielectric-barrier-discharge surface plasma,

Physics of fluids 21, 094106 (2009).


10 G. Artana, A. Cammilleri, J. Carlier, and E. Memin, Strong and weak constraint variational assimilations for reduced order modelling

for flow control, Physics of fluids 8, 32643288 (2012).


11 C. Rowley, Model reduction for fluid flows using balanced proper orthogonal decomposition, Int. J. Bifurc. Chaos 15, 9971013 (2005).
12 A. Barbagallo, D. Sipp, and P. Schmid, Why may reduced order models based on global modes not work for closed loop control?

(2009).
13 J.-N. Juang and M. Phan, Deadbit predictive controllers, Technical Memorandum 112862 (Nasa, 1997).
14 M. A. Kegerise, R. H. Cabell, and L. N. Cattafesta, Real time feedback control of flow-induced cavity tones - part 1: Fixed-gain

control, Journal of Sound and Vibration 307, 906923 (2007).


15 M. A. Kegerise, R. H. Cambell, and L. N. Cattafesta, Real time feedback control of flow-induced cavity tones - part 2: Adaptive

control, Journal of Sound and Vibration 307, 924940 (2007).


16 S.-C. Huang and J. Kim, Control and system identification of a separated flow, Physics of Fluids 20 (2008).
17 A. Herve, D. Sipp, P. J. Schmid, and M. Samuelides, A physics-based approach to flow control using system identification, Journal

of Fluid Mechanics 702, 2658 (2012).


18 R. T. Fomena and C. Collewet, Fluid flow control: a vision-based approach, International Journal of Flow Control 3, 133169 (2011).
19 M. Gharib, C. Willert, and M. Munson, Real-time particle image velocimetry for closed-loop flow control applications, (2010).
20 J. A. N. Gauthier, Control of the detached flow behind a backward facing step by visual feedback, ArXiv 1306.4554v (2013).
21 J. DAdamo, L. M. Gonzalez, A. Gronskis, and G. Artana, The scenario of two-dimensional instabilities of the cylinder wake under

electrohydrodynamic forcing: a linear stability analysis, Fluid Dynamics Research 44, 20 (2012).
22 F. Archambeau, N. Mchitoua, and M. Sakiz, Code_saturne: a finite volume code for the computation of turbulent incompressible

flows, International Journal on Finite Volumes 1 (2004).

Apendice E. Publicaciones 150


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

19

23 J. R. Roth, D. M. Sherman, and S. P. Wilkinson, Electrohydrodynamic flow control with a glow-discharge surface plasma, AIAA
Journal 38, 11661172 (2000).
24 A. Gronskis, R. Sosa, and G. Artana, Modelling ehd actuation with a slip velocity, (2009).
25 L. Ljung, System Identification: Theory for the User (Prentice-Hall Inc., Englewood Cliffs, N.J., 1987).
26 G. Tadmor, O. Lehmann, B. R. Noack, and M. Morzynski, Mean field representation of the natural and actuated cylinder wake,

Physics of Fluids 22, 034102 (2010).


27 H. Choi, W. Jeon, and J. Kim, Control of flow over a bluff body, Annual Review of Fluid Mechanics 40, 113139 (2008).
28 K. Cohen, S. Aradag, S. Siegel, J. Seidel, and T. McLaughlin, Low Reynolds Aerodynamics and Transition (edt by Mustafa Serdar

Genc, InTech Europe, 2012) Chap. 6, pp. 117138.


29 L. N. Cattafesta, Q. Song, D. R. Williams, C. W. Rowley, and F. S. Alvi, Active control of flow-induced cavity oscillations, Progress

in Aerospace Sciences 44, 479502 (2008).


30 E. Gillies, Low-dimensional control of the circular cylinder wake, Journal of Fluid Mechanics 371, 157178 (1998).
31 K. Roussopoulos, Feedback control of vortex shedding at low reynolds number, Journal of Fluid Mechanics 248, 267296 (1993).

Apendice E. Publicaciones 151


F Codigos Fuente

F.1. Extension del Mallado 2D a 3D

% Rutina para extrudar una malla 2D del GID (leida en formato .msh)
% una distancia dz y guardarla con formato .msh para utilizar en code saturne

close all;clear all


%numero de layers: condiciones de borde
layers_number=6;
% %espesor de extrudado
dz=5*1e-3;
%factor de escala para cambiar la unidad de medida de todos los nodos procesados
escala=1;
%nombre del archivo inicial
unit1=cilindro.noestructurado.dat;
%nombre del archivo final
unit2=cilindro.noestructurado.msh;

% Lectura de la malla 2D
fid = fopen(unit1, r);
nnodes = textscan(fid, %f, 1, headerlines, 4);
node_coords = textscan(fid, %f %f %f, nnodes{1});
nelems = textscan(fid, %f, 1, headerlines, 3);
elems = textscan(fid, %f %f %f %f %f %f %f %f %f, nelems{1});
layers = textscan(fid, %d %q, layers_number, headerlines, 3);
fclose(fid);

%deteccion del nro de BC asociado a simetria


Lnumber = -1;
for i=1:layers_number
name=char(layers{2}(i));
K=strcmp(name,simetria);
if K==1
Lnumber=layers{1}(i);
end
end
if Lnumber == -1
Lnumber=layers_number+1;
end

% Matriz de coordenadas de nodos: [nNodo x y z]


node_coordstot(1:nnodes{1},1)=node_coords{1};
node_coordstot(1:nnodes{1},2)=node_coords{2}*escala;
node_coordstot(1:nnodes{1},3)=node_coords{3}*escala;
node_coordstot(1:nnodes{1},4)=0.0*escala;
node_coordstot(nnodes{1}+1:2*nnodes{1},1)=node_coords{1}+nnodes{1};
node_coordstot(nnodes{1}+1:2*nnodes{1},2)=node_coords{2}*escala;
node_coordstot(nnodes{1}+1:2*nnodes{1},3)=node_coords{3}*escala;
node_coordstot(nnodes{1}+1:2*nnodes{1},4)=dz;

%Matriz de conectividad
n1=0;n2=0;n3=0;
for i=1:nelems{1}
if elems{2}(i)==1
n1=n1+1;

152
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

elseif elems{2}(i)==2
n2=n2+1;
elseif elems{2}(i)==3
n3=n3+1;
end
end

nelems_lin=n1;
nelems_tri=n2;
nelems_quad=n3;
nelemens_tot=nelems_lin+3*(nelems_tri+nelems_quad);
Elemconec1=zeros(nelems_lin,9);
Elemconec2=zeros(2*nelems_tri,8);
Elemconec3=zeros(2*nelems_quad,9);
Elemconec4=zeros(nelems_tri,11);
Elemconec5=zeros(nelems_quad,13);
n1=0;n2=0;n3=0;n4=0;n5=0;

for i=1:nelems{1}
if elems{2}(i)==1
n1=n1+1;
%elementos de superficie rectangulares (frontera)
Elemconec1(n1,1)=i;
Elemconec1(n1,2)=3;
Elemconec1(n1,3)=elems{3}(i);
Elemconec1(n1,4)=elems{4}(i);
Elemconec1(n1,5)=elems{5}(i);
Elemconec1(n1,6)=elems{6}(i);
Elemconec1(n1,7)=elems{6}(i)+nnodes{1};
Elemconec1(n1,8)=elems{7}(i)+nnodes{1};
Elemconec1(n1,9)=elems{7}(i);
end
end
nparcial=nelems_lin;
for i=1:nelems{1}
if elems{2}(i)==2
n2=n2+1;
%elementos de superficie triangulares (simentroa)
Elemconec2(n2,1)=n2+nparcial;
Elemconec2(n2,2)=elems{2}(i);
Elemconec2(n2,3)=elems{3}(i);
Elemconec2(n2,4)=Lnumber;
Elemconec2(n2,5)=elems{5}(i);
Elemconec2(n2,6)=elems{6}(i);
Elemconec2(n2,7)=elems{7}(i);
Elemconec2(n2,8)=elems{8}(i);
%elementos de superficie triangulares (la otra siemtroa en z=dz)
Elemconec2(n2+nelems_tri,1)=n2+nparcial+nelems_tri;
Elemconec2(n2+nelems_tri,2)=elems{2}(i);
Elemconec2(n2+nelems_tri,3)=elems{3}(i);
Elemconec2(n2+nelems_tri,4)=Lnumber;
Elemconec2(n2+nelems_tri,5)=elems{5}(i);
Elemconec2(n2+nelems_tri,6)=elems{8}(i)+nnodes{1};
Elemconec2(n2+nelems_tri,7)=elems{7}(i)+nnodes{1};
Elemconec2(n2+nelems_tri,8)=elems{6}(i)+nnodes{1};
end
end
nparcial=2*nelems_tri+nelems_lin;
for i=1:nelems{1}
if elems{2}(i)==3
n3=n3+1;
%elementos de superficie cuadrangulares (simentroa)
Elemconec3(n3,1)=n3+nparcial;
Elemconec3(n3,2)=elems{2}(i);
Elemconec3(n3,3)=elems{3}(i);
Elemconec3(n3,4)=Lnumber;
Elemconec3(n3,5)=elems{5}(i);
Elemconec3(n3,6)=elems{6}(i);
Elemconec3(n3,7)=elems{7}(i);
Elemconec3(n3,8)=elems{8}(i);

Apendice F. Codigos Fuente 153


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Elemconec3(n3,9)=elems{9}(i);
%elementos de superficie cuadrangulares (simentroa)
Elemconec3(n3+nelems_quad,1)=n3+nparcial+nelems_quad;
Elemconec3(n3+nelems_quad,2)=elems{2}(i);
Elemconec3(n3+nelems_quad,3)=elems{3}(i);
Elemconec3(n3+nelems_quad,4)=Lnumber;
Elemconec3(n3+nelems_quad,5)=elems{5}(i);
Elemconec3(n3+nelems_quad,6)=elems{9}(i)+nnodes{1};
Elemconec3(n3+nelems_quad,7)=elems{8}(i)+nnodes{1};
Elemconec3(n3+nelems_quad,8)=elems{7}(i)+nnodes{1};
Elemconec3(n3+nelems_quad,9)=elems{6}(i)+nnodes{1};
end
end
nparcial=2*nelems_tri+nelems_lin+2*nelems_quad;
for i=1:nelems{1}
if elems{2}(i)==2
n4=n4+1;
%elementos de volumen tipo prisma
Elemconec4(n4,1)=nparcial+n4;
Elemconec4(n4,2)=6;
Elemconec4(n4,3)=elems{3}(i);
Elemconec4(n4,4)=elems{4}(i);
Elemconec4(n4,5)=elems{5}(i);
Elemconec4(n4,6)=elems{6}(i);
Elemconec4(n4,7)=elems{7}(i);
Elemconec4(n4,8)=elems{8}(i);
Elemconec4(n4,9)=elems{6}(i)+nnodes{1};
Elemconec4(n4,10)=elems{7}(i)+nnodes{1};
Elemconec4(n4,11)=elems{8}(i)+nnodes{1};
end
end
nparcial=3*nelems_tri+nelems_lin+2*nelems_quad;
for i=1:nelems{1}
if elems{2}(i)==3
n5=n5+1;
%elementos de volumen tipo hexahedro
Elemconec5(n5,1)=n5+nparcial;
Elemconec5(n5,2)=5;
Elemconec5(n5,3)=elems{3}(i);
Elemconec5(n5,4)=elems{4}(i);
Elemconec5(n5,5)=elems{5}(i);
Elemconec5(n5,6)=elems{7}(i)+nnodes{1};
Elemconec5(n5,7)=elems{8}(i)+nnodes{1};
Elemconec5(n5,8)=elems{8}(i);
Elemconec5(n5,9)=elems{7}(i);
Elemconec5(n5,10)=elems{6}(i)+nnodes{1};
Elemconec5(n5,11)=elems{9}(i)+nnodes{1};
Elemconec5(n5,12)=elems{9}(i);
Elemconec5(n5,13)=elems{6}(i);
end
end

% Almacenamiento del archivo .msh


reng1=$MeshFormat;
reng2=2 0 8;
reng3=$EndMeshFormat;
reng4=$Nodes;
reng5=$EndNodes;
reng6=$Elements;
reng7=$EndElements;
reng8=$PhysicalNames;
reng9=$EndPhysicalNames;
fid2 = fopen(unit2,w);
fprintf(fid2, %s\n, reng1);
fprintf(fid2, %s\n, reng2);
fprintf(fid2, %s\n, reng3);
fprintf(fid2, %s\n, reng4);
fprintf(fid2, %d\n, nnodes{1}*2);
fprintf(fid2, %d %g %g %g\n, node_coordstot);
fprintf(fid2, %s\n, reng5);

Apendice F. Codigos Fuente 154


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

fprintf(fid2, %s\n, reng6);


fprintf(fid2, %d\n, nelemens_tot);
if n1>0
fprintf(fid2, %d %d %d %d %d %d %d %d %d\n, Elemconec1);
end
if n2>0
fprintf(fid2, %d %d %d %d %d %d %d %d\n, Elemconec2);
end
if n3>0
fprintf(fid2, %d %d %d %d %d %d %d %d %d\n, Elemconec3);
end
if n4>0
fprintf(fid2, %d %d %d %d %d %d %d %d %d %d %d\n, Elemconec4);
end
if n5>0
fprintf(fid2, %d %d %d %d %d %d %d %d %d %d %d %d %d\n, Elemconec5);
end

fprintf(fid2, %s\n, reng7);


fprintf(fid2, %s\n, reng8);
layers_numbers=layers{1};
layers_names=char(layers{2});
for i=1:layers_number
number=layers{1}(i);
name=char(layers{2}(i));
fprintf(fid2, %d %s\n, number, name);
end
if K==0
number=Lnumber;
name=simetria;
fprintf(fid2, %d %s\n, number, name);
end
fprintf(fid2, %s\n, reng9);
fclose(fid2);

F.2. Conversion del Mallado Irregular a una Grilla Cartesiana


F.2.1. chrCleanFolderIfExists.m

function chrCleanFolderIfExists( folder )


if exist(folder, dir)
rmdir(folder, s);
end
mkdir(folder);

end

F.2.2. chrComputeAverage.m

function [ average ] = chrComputeAverage( filepaths , geo, isVector)


count = length(filepaths);
fprintf(Computing average for %d files.\n, count);
if count < 1
throw MException(InvalidFileList:NotEnoughFiles, It was not possible to compute the average for
the given file list);
end

average = chrReadBinaryContent(filepaths{1}, geo, isVector);


for step = 2:count
content = chrReadBinaryContent(filepaths{step}, geo, isVector);
average = average + (content - average) / step;
end

Apendice F. Codigos Fuente 155


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

fprintf(Average computation finished.\n);


end

F.2.3. chrComputeVorticityAverageForGeoXY.m

function [ vorticityZ ] = chrComputeVorticityAverageForGeoXY( filepaths , geo, geoXY)


count = length(filepaths);
fprintf(Computing average vorticity for %d files.\n, count);
if count < 1
throw MException(InvalidFileList:NotEnoughFiles, It was not possible to compute the average for
the given file list);
end

average = chrComputeAverage(filepaths, geo, true);

fprintf(Transforming average to XY...\n);


averageXY = geoTransformContentToXY(average, geo, geoXY);

%content = chrReadBinaryContent(filepaths{1}, geo, true);


%contentXY = geoTransformContentToXY(content, geo, geoXY);

[x,y] = meshgrid(geoXY.gridValues.x,geoXY.gridValues.y);

u = averageXY(:,:,1); v= averageXY(:,:,2);
fprintf(Computing vorticity...\n);
vorticityZ = curl(x,y,u,v);
vorticityZ = vorticityZ;

fprintf(Average Vorticity computation finished.\n);


end

F.2.4. chrExtractBinaryHeader.m

function [ header ] = chrExtractBinaryHeader( filepath )


headerCharacters = chrGetAmountOfHeadingCharacters();
file = fopen(filepath, rb);
if file < 1
throw(MException(FileError:CannotOpenTheFile, strcat(There was an error trying to open the file:
", filepath, ".)));
end
header = fread(file, headerCharacters, char*1=>char);
fclose(file);
end

F.2.5. chrFindFiles.m

function [ filepaths ] = chrFindFiles( settings )


filesFilter = strcat(settings.folder, /, settings.filenamesFilter);
fprintf(Seeking files under " %s"\n, filesFilter);
filenamesStruct = dir(filesFilter);
filenames = {filenamesStruct.name};
filepaths = strcat(repmat(strcat(settings.folder,/), length(filenames),1),filenames);
filepaths = sort(filepaths);
filepathsCount = length(filepaths);
fileMin = max(1, settings.filerangeFilter.min);
fileMax = min(filepathsCount, settings.filerangeFilter.max);
filepaths = filepaths(fileMin:fileMax);
end

Apendice F. Codigos Fuente 156


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.2.6. chrFindFilesAndComputeAverage.m

function chrFindFilesAndComputeAverage( settings )


filepaths = chrFindFiles(settings);
geoFilepath = strcat(settings.folder, /, settings.geoFilename);
if settings.isVector
outputFilename = chr.vectoraverage;
else
outputFilename = chr.scalaraverage;
end
outputFilepath = strcat(settings.outputFolder, /, outputFilename);
outputCaseFilepath = strcat(settings.outputFolder, /CHR.case);

geo = chrReadBinaryGeo(geoFilepath);
average = chrComputeAverage(filepaths, geo, settings.isVector);
chrCleanFolderIfExists(settings.outputFolder);
header = chrExtractBinaryHeader(filepaths{1});
chrWriteBinaryContent(header, average, outputFilepath);
%ignore copyResult variable since it could fail because of user permissions
%in the OS
copyResult = copyfile(geoFilepath, settings.outputFolder);

chrWriteCaseFile(outputCaseFilepath, outputFilename, settings.geoFilename, settings.isVector);


end

F.2.7. chrGetAmountOfHeadingCharacters.m

function [ headingCharacters ] = getAmountOfHeadingCharacters( )


headingCharacters = 80 ... % description line 1 (80 chars)
+ 80 ... % part (80 chars)
+ 4 ... % # (1 int)
+ 80; % coordinates (80 chars)
end

F.2.8. chrReadBinaryContent.m

function [ content ] = readBinaryContent( filepath, geo, isVector)


file = fopen(filepath, rb);
if file < 1
throw(MException(FileError:CannotOpenTheFile, strcat(There was an error trying to open the file:
", filepath, ".)));
end
if isVector
valuesPerCell = 3;
else
valuesPerCell = 1;
end

headerCharacters = chrGetAmountOfHeadingCharacters();
fseek(file, headerCharacters, -1);

content = fread(file, length(geo.cells) * valuesPerCell, float32=>double);


content = reshape(content, length(geo.cells), valuesPerCell);
fclose(file);
end

F.2.9. chrReadBinaryGeo.m

function [ geo ] = chrReadBinaryGeo( filepath )

Apendice F. Codigos Fuente 157


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

file = fopen(filepath, rb);


if file < 1
throw(MException(FileError:CannotOpenTheFile, strcat(There was an error trying to open the file:
", filepath, ".)));
end

headerCharacters = 80 + ... %CBinary format


80 + 80 + ... %Description lines
80 + ... %node id
80 + ... %element id %80 + ... %extends optional %6*4 + ... %min,max, etc optional
80 + ... %part
4 + ... %part number
80 + ... %description
80 ; %coordinates

fseek(file, headerCharacters, -1);


countCoordinates = fread(file, 1, int32=>int);
coordinates = fread(file, countCoordinates*3, float32=>double);
fseek(file, 80, 0); %penta6 assumed
countCells = fread(file, 1, int32=>int);
cells = fread(file, countCells*6, int32=>double);
fclose(file);
geo.coordinates = reshape(coordinates, countCoordinates, 3);
geo.cells = reshape(cells, 6, countCells);
end

F.2.10. chrReadVelocity2D.m

function [ velocity ] = chrReadVelocity2D(filepaths , geo, geoXY, clipArea)


isVector = true;
qtyFiles = length(filepaths);
fprintf(Reading values and transforming to XY. %d files.\n, qtyFiles);
if qtyFiles < 1
throw MException(InvalidFileList:NotEnoughFiles, It was not possible to compute the average for
the given file list);
end

areaX = find(geoXY.gridValues.x >= clipArea.x1 & geoXY.gridValues.x <= clipArea.x2);


areaY = find(geoXY.gridValues.y >= clipArea.y1 & geoXY.gridValues.y <= clipArea.y2);
velocity.u = zeros(length(areaX), length(areaY), qtyFiles);
velocity.v = zeros(size(velocity.u));
for step = 1:qtyFiles
fprintf(Reading file %d.\n, step);
content = chrReadBinaryContent(filepaths{step}, geo, isVector);
contentXY = geoTransformContentToXY(content, geo, geoXY);
contentXY = contentXY(areaX, areaY,:);
velocity.u(:,:, step) = contentXY(:,:,1);
velocity.v(:,:, step) = contentXY(:,:,2);
end
fprintf(Reading and transforming to XY finished.\n);
end

F.2.11. chrWriteBinaryContent.m

function writeBinaryContent( header, content, outputFilepath )


file = fopen(outputFilepath, wb);
if file < 1
throw(MException(FileError:CannotWriteTheFile, strcat(There was an error trying to write the
file: ", filepath, ".)));
end
fwrite(file, header, char*1);
fwrite(file, content, float32);
fclose(file);
end

Apendice F. Codigos Fuente 158


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.2.12. chrWriteCaseFile.m

function chrWriteCaseFile( filepath, valuesFilename, geoFilename, isVector )


file = fopen(filepath, wt);

fprintf(file, FORMAT\ntype: ensight gold\n\n);


fprintf(file, GEOMETRY\nmodel: %s\n\n, geoFilename);
if isVector
fprintf(file, VARIABLE\nvector per element: %s %s\n, valuesFilename,valuesFilename);
else
fprintf(file, VARIABLE\nscalar per element: %s %s\n, valuesFilename,valuesFilename);
end

fclose(file);
end

F.2.13. geoComputeIntersectionArea.m

function area = geoComputeIntersectionArea(xyTriangle, rect, delta, gridBounds)


x1 = rect(1)*delta + gridBounds.minX;
y1 = rect(2)*delta + gridBounds.minY;
x2 = (rect(1)+1)*delta + gridBounds.minX;
y2 = (rect(2)+1)*delta + gridBounds.minY;
% create a counter-clockwise rectangle for the clip operation
xyRect = [x1 y1; x2 y1; x2 y2; x1 y2];

clip = polygonClip(xyTriangle, xyRect);


if isempty(clip)
area = 0;
else
area = polygonArea(clip);
end
end

F.2.14. geoGetBoundingRectsForDelta.m

function rects = geoGetBoundingRectsForDelta(xyTriangle, delta, bounds, gridBounds)


maxX = max(xyTriangle(:,1));
minX = min(xyTriangle(:,1));
maxY = max(xyTriangle(:,2));
minY = min(xyTriangle(:,2));

xCellsUpToMin = floor((minX - bounds.minX) / delta);


xCellsUpToMax = floor((maxX - bounds.minX) / delta);
yCellsUpToMin = floor((minY - bounds.minY) / delta);
yCellsUpToMax = floor((maxY - bounds.minY) / delta);

xCellsUpToMin = max(xCellsUpToMin, gridBounds.minX);


xCellsUpToMax = min(xCellsUpToMax, gridBounds.maxX);
yCellsUpToMin = max(yCellsUpToMin, gridBounds.minY);
yCellsUpToMax = min(yCellsUpToMax, gridBounds.maxY);

rects = zeros((xCellsUpToMax - xCellsUpToMin + 1)*(yCellsUpToMax - yCellsUpToMin + 1), 2);


iiRect = 1;
for xx=xCellsUpToMin:xCellsUpToMax
for yy=yCellsUpToMin:yCellsUpToMax
rects(iiRect, :) =[xx, yy];
iiRect = 1 + iiRect;

Apendice F. Codigos Fuente 159


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

end
end
end

F.2.15. geoTransformContentToNonXY.m

function [ content ] = geoTransformContentToNonXY( contentXY, geo, geoXY )


contentXYCoordinatesCount = size(contentXY,3);
rowCount = size(geo.cells,1);
content = zeros(rowCount, contentXYCoordinatesCount);
for ii=1:rowCount
cellRectAndRatios = geoXY.cellsRectTargetAndRatio{ii};
contentCoords = 1:contentXYCoordinatesCount;
cellContent = zeros(1,1,contentXYCoordinatesCount);
for jj=1:length(cellRectAndRatios)
x = cellRectAndRatios{jj}.rect(1)+1;
y = cellRectAndRatios{jj}.rect(2)+1;
cellContent = cellContent + contentXY(x,y,contentCoords)*cellRectAndRatios{jj}.
ratioIntersectionTri;
end
content(ii,:) = reshape(cellContent, 1,contentXYCoordinatesCount,1);
end
end

F.2.16. geoTransformContentToXY.m

function [ contentXY ] = geoTransformContentToXY( content, geo, geoXY )


contentCoordinatesCount = size(content,2);
contentXY = zeros(geoXY.gridBounds.maxX + 1, geoXY.gridBounds.maxY + 1, contentCoordinatesCount);
rowCount = size(content, 1);
for ii=1:rowCount
cellRectAndRatios = geoXY.cellsRectTargetAndRatio{ii};
contentCoords = 1:contentCoordinatesCount;
cellContent = reshape(content(ii, contentCoords), 1,1,contentCoordinatesCount);
for jj=1:length(cellRectAndRatios)
x = cellRectAndRatios{jj}.rect(1)+1;
y = cellRectAndRatios{jj}.rect(2)+1;
contentXY(x,y,contentCoords) = contentXY(x,y,contentCoords) + cellRectAndRatios{jj}.
ratioIntersectionRect * cellContent;

end

end
end

F.2.17. geoTransformMeshToXYGrid.m

function [ geoXY ] = geoTransformMeshToXYGrid( geo, xyStep)

minBounds = min(geo.coordinates);
maxBounds = max(geo.coordinates);
bounds.minX = minBounds(1);
bounds.minY = minBounds(2);
bounds.maxX = maxBounds(1);
bounds.maxY = maxBounds(2);
gridBounds.minX = 0;
gridBounds.maxX = floor((bounds.maxX - bounds.minX)/xyStep);
if ~mod(bounds.maxX - bounds.minX, xyStep)
gridBounds.maxX = gridBounds.maxX - 1;
end

Apendice F. Codigos Fuente 160


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

gridBounds.minY = 0;
gridBounds.maxY = floor((bounds.maxY - bounds.minY)/xyStep);
if ~mod(bounds.maxY - bounds.minY, xyStep)
gridBounds.maxY = gridBounds.maxY - 1;
end

if ~mod(bounds.maxX-bounds.minX,xyStep)
maxXValue = bounds.maxX - xyStep;
else
maxXValue = bounds.maxX;
end
if ~mod(bounds.maxY-bounds.minY,xyStep)
maxYValue = bounds.maxY - xyStep;
else
maxYValue = bounds.maxY;
end
gridValues.x = bounds.minX:xyStep:maxXValue;
gridValues.y = bounds.minY:xyStep:maxYValue;

cellsCount = size(geo.cells, 1);


rectArea = xyStep*xyStep;
cells = geo.cells;
xyCoordinates = geo.coordinates(:,1:2);
cellsRectTargetAndRatio = cell(cellsCount, 1);
parfor ii = 1:cellsCount
currentCell = cells(ii,:);
xyTriangle = xyCoordinates(currentCell(1:3),:);
triArea = polygonArea(xyTriangle);
boundingRects = geoGetBoundingRectsForDelta(xyTriangle, xyStep, bounds, gridBounds);
rectsCount = size(boundingRects, 1);
cellRectAndRatio = {};
iiCellRectAndRatio = 0;
for jj=1:rectsCount
rect = boundingRects(jj,:);
intersectionArea = geoComputeIntersectionArea(xyTriangle, rect, xyStep, bounds);
if intersectionArea > 0
iiCellRectAndRatio = iiCellRectAndRatio +1;
cellRectAndRatio{iiCellRectAndRatio}.rect = rect;
cellRectAndRatio{iiCellRectAndRatio}.ratioIntersectionRect = intersectionArea/rectArea;
cellRectAndRatio{iiCellRectAndRatio}.ratioIntersectionTri = intersectionArea/triArea;
end
end
cellsRectTargetAndRatio{ii} = cellRectAndRatio;
end
geoXY.gridValues = gridValues;
geoXY.gridBounds = gridBounds;
geoXY.bounds = bounds;
geoXY.step = xyStep;
geoXY.cellsRectTargetAndRatio = cellsRectTargetAndRatio;
end

F.2.18. polygonArea.m

function area = polygonArea(polygon)


%assumes clockwise orientation
%reference: http://alienryderflex.com/polygon_area/
area = 0;
points = size(polygon, 1);
jj = points;
for ii = 1:points
area = area + (polygon(jj, 1) + polygon(ii, 1))*(polygon(jj,2)-polygon(ii,2));
jj = ii;
end
area = area * 0.5;
%do not take care on clockwise or counterclockwise polygons, just take positive areas.
area = abs(area);
end

Apendice F. Codigos Fuente 161


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.2.19. polygonClip.m

function clippedPolygon = polygonClip(subjectPolygon,clipPolygon)


%reference: http://rosettacode.org/wiki/Sutherland-Hodgman_polygon_clipping#MATLAB
% % Helper Functions
%computerIntersection() assumes the two lines intersect
function intersection = computeIntersection(line1,line2)

%this is an implementation of
%http://en.wikipedia.org/wiki/Line-line_intersection

intersection = zeros(1,2);

detL1 = det(line1);
detL2 = det(line2);

detL1x = det([line1(:,1),[1;1]]);
detL1y = det([line1(:,2),[1;1]]);

detL2x = det([line2(:,1),[1;1]]);
detL2y = det([line2(:,2),[1;1]]);

denominator = det([detL1x detL1y;detL2x detL2y]);

intersection(1) = det([detL1 detL1x;detL2 detL2x]) / denominator;


intersection(2) = det([detL1 detL1y;detL2 detL2y]) / denominator;

end %computeIntersection

%inside() assumes the boundary is oriented counter-clockwise


function in = inside(point,boundary)

pointPositionVector = [diff([point;boundary(1,:)]) 0];


boundaryVector = [diff(boundary) 0];
crossVector = cross(pointPositionVector,boundaryVector);

if ( crossVector(3) <= 0 )
in = true;
else
in = false;
end

end %inside

% % Sutherland-Hodgman Algorithm

clippedPolygon = subjectPolygon;
numVerticies = size(clipPolygon,1);
clipVertexPrevious = clipPolygon(end,:);

for clipVertex = (1:numVerticies)


if ~isempty(clippedPolygon)
clipBoundary = [clipPolygon(clipVertex,:) ; clipVertexPrevious];

inputList = clippedPolygon;

clippedPolygon = [];
previousVertex = inputList(end,:);

for subjectVertex = (1:size(inputList,1))

if ( inside(inputList(subjectVertex,:),clipBoundary) )

if( not(inside(previousVertex,clipBoundary)) )
subjectLineSegment = [previousVertex;inputList(subjectVertex,:)];
clippedPolygon(end+1,1:2) = computeIntersection(clipBoundary,subjectLineSegment);
end

clippedPolygon(end+1,1:2) = inputList(subjectVertex,:);

Apendice F. Codigos Fuente 162


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

elseif( inside(previousVertex,clipBoundary) )
subjectLineSegment = [previousVertex;inputList(subjectVertex,:)];
clippedPolygon(end+1,1:2) = computeIntersection(clipBoundary,subjectLineSegment);
end

previousVertex = inputList(subjectVertex,:);
clipVertexPrevious = clipPolygon(clipVertex,:);

end %for subject verticies


end %if not empty
end %for boundary verticies
end %sutherlandHodgman algorithm

F.3. Calculo de Energa Cinetica y RMS de las Fluctuaciones


F.3.1. plotEnergy.m

if ~exist(results, var)
processEnergy;
end

result = results{1};
settings.noActuationMean.start = 1;
settings.noActuationMean.end = 50;
settings.actuationMean.start = 409;
settings.actuationMean.end = 891;
amountOfMarkersInPlot = 0;
timeStepRange = [1 5000];

stepsQty = length(result.energy);
plotSteps = timeStepRange(1):timeStepRange(2);
markerSteps = 1:floor(max(timeStepRange)/amountOfMarkersInPlot):max(timeStepRange);

noActuationMean = mean(result.energy(settings.noActuationMean.start:settings.noActuationMean.end));
actuationMean = mean(result.energy(settings.actuationMean.start:settings.actuationMean.end));

currentFigure = figure;
handleKinetic = plot(NaN,NaN,k-,plotSteps, spline(result.steps,result.energy, plotSteps), k-,
markerSteps, spline(result.steps,result.energy, markerSteps),ko,LineWidth, 2, MarkerFaceColor,
k, MarkerSize, 5);
hold on;
handleMeanNoAct = plot(result.steps,repmat(noActuationMean, stepsQty,1),r-., LineWidth, 2);
handleMeanAct = plot(result.steps,repmat(actuationMean, stepsQty,1),b--, LineWidth, 2);
%grid on;
legend([handleKinetic(1), handleMeanNoAct, handleMeanAct], {Instantaneous, Mean (Non-actuated), Mean (
Actuated)})
xlabel(Time Step Number, FontSize, 22);
ylabel(Energy of Fluctuations, FontSize, 22);
currentAxes = get(currentFigure,CurrentAxes);
currentAxis = axis;
axis(currentAxes, [timeStepRange currentAxis(3:4)]);
set(currentAxes,FontSize,18);
title(Kinetic energy of fluctuations per unit area - Transition from non-actuated to actuated);

F.3.2. processEnergy.m

resultsFilepath = ScenarioResults.mat;
if exist(resultsFilepath, file)
load(resultsFilepath);
else
xyStep = 0.045;
%cacheFolder = /Users/invitado/tmp/cache;

Apendice F. Codigos Fuente 163


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

cacheFolder = /media/Datos/Pablo/Workspace/tmp/cache/0.045;

% Actuation p90 - g4 - From step 1 to 50 (noAct) and 51 to 900 (act)


settings.name = p90_rate1_g4_q1.4_including_noactuation;
%settings.folder = /Users/invitado/tmp/TESIS_RESULTS/16_KEGERISE_LAGRANGE_p90_g4_1.4_1.4_1.4_1.4/CHR.
ENSIGHT.01031126;
settings.folder = /media/Datos/Pablo/Workspace/Saturne/TESIS_RESULTS/16_KEGERISE_LAGRANGE_p90_g4_1.4_1
.4_1.4_1.4_7000steps/CHR.ENSIGHT.03262049;
settings.filerangeFilter.min = 1;
settings.filerangeFilter.max = Inf;
settings.clipArea.x1 = -5;
settings.clipArea.y1 = -5;
settings.clipArea.x2 = 20;
settings.clipArea.y2 = 5;
ntchr = 10;

integrationArea = struct(x1, -5, y1, -5, x2, 20, y2, 5);

settings.filenamesFilter = chr.velocity*;
settings.geoFilename = chr.geo;
settings.outputFolder = Out;
settings.isVector = true;

outputFilename = chr.velocityaverage;
filepaths = chrFindFiles(settings);
geoFilepath = strcat(settings.folder, /, settings.geoFilename);
outputFilepath = strcat(settings.outputFolder, /, outputFilename);
outputCaseFilepath = strcat(settings.outputFolder, /CHR.case);

geoCacheFilename = sprintf(geo.cache.xyStep. %.3f.mat, xyStep);


if exist(geoCacheFilename, file)
fprintf(Loading geo files from cache ( %s)\n, geoCacheFilename);
result = load(geoCacheFilename);
geo = result.geo;
geoXY = result.geoXY;
clear result;
else
fprintf(Computing geo data\n);
geo = chrReadBinaryGeo(geoFilepath);
fprintf(Computing geoXY data\n);
tic;
geoXY = geoTransformMeshToXYGrid(geo, xyStep);
toc;
fprintf(Saving geo files to cache ( %s)\n, geoCacheFilename);
save(geoCacheFilename, geo, geoXY);
end

if any( strcmp(fieldnames(settings), clipArea ))


clipAreaFlag = sprintf(.clipped. %.1f. %.1f. %.1f. %.1f, settings.clipArea.x1, settings.clipArea.y1,
settings.clipArea.x2, settings.clipArea.y2);
else
clipAreaFlag = ;
end
velocityXYCacheFilename = sprintf( %s/binaries.cache.xy. %s %s.mat, cacheFolder, settings.name,
clipAreaFlag);
if exist(velocityXYCacheFilename, file)
fprintf(Loading velocityXY from cache ( %s)\n, velocityXYCacheFilename);
result = load(velocityXYCacheFilename);
velocityXY = result.velocityXY;
clear result;
else
fprintf(Cache %s not found. Computing velocity data\n, velocityXYCacheFilename);
tic;
velocityXY = chrReadVelocity2D(filepaths, geo, geoXY, settings.clipArea);
toc;
fprintf(Saving velocityXY to cache ( %s)\n, velocityXYCacheFilename);
save(velocityXYCacheFilename, velocityXY);
end

Apendice F. Codigos Fuente 164


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

[xIntegration, yIntegration] = selectIntegrationCoordinates(geoXY, settings.clipArea, integrationArea);


sizeVelocity = [1 1 size(velocityXY.u, 3)];
kineticEnergyPerturb = 0.5 * ((velocityXY.u(xIntegration, yIntegration,:)-repmat(mean(velocityXY.u(
xIntegration, yIntegration,:),3), sizeVelocity)).^2+ ...
(velocityXY.v(xIntegration, yIntegration,:)-repmat(mean(velocityXY.v(
xIntegration, yIntegration,:),3), sizeVelocity)).^2);
clear velocityXY;

kineticEnergyPerturbInt = sum(sum(kineticEnergyPerturb, 1), 2);


stepsQty = size(kineticEnergyPerturbInt, 3);
steps = 1:ntchr:stepsQty*ntchr;
integrationSurface = (integrationArea.x2-integrationArea.x1) * (integrationArea.y2-integrationArea.y1)/
xyStep^2;
kineticEnergyPerturbIntNormalized = reshape(kineticEnergyPerturbInt, stepsQty, 1)/integrationSurface;

result = struct();
result.ntchr = ntchr;
result.energy = kineticEnergyPerturbIntNormalized;
result.steps = steps;

save(resultsFilepath, results);
end

F.3.3. processRmsCriteria.m

PLOT = true;
xyStep = 0.045;
%cacheFolder = /Users/invitado/tmp/cache;
cacheFolder = /media/Datos/Pablo/Workspace/tmp/cache;

% No Actuation - From step 1000 to step 11100


settings.name = noactuation;
%settings.folder = /Users/invitado/tmp/TESIS_RESULTS/11_NO_ACTUATION_R235/CHR.ENSIGHT.01251100;
settings.folder = /media/Datos/Pablo/Workspace/Saturne/TESIS_RESULTS/11_NO_ACTUATION_R235/CHR.ENSIGHT
.01251100;
settings.filerangeFilter.min = 50;
settings.filerangeFilter.max = 250;
settings.minXToSeekForPeak = 0.5;
settings.minYToSeekForPeak = 0;

settings.filenamesFilter = chr.velocity*;
settings.geoFilename = chr.geo;
settings.outputFolder = Out;
settings.isVector = true;

outputFilename = chr.velocityaverage;
filepaths = chrFindFiles(settings);
geoFilepath = strcat(settings.folder, /, settings.geoFilename);
outputFilepath = strcat(settings.outputFolder, /, outputFilename);
outputCaseFilepath = strcat(settings.outputFolder, /CHR.case);

geoCacheFilename = sprintf(geo.cache.xyStep. %.3f.mat, xyStep);


if exist(geoCacheFilename, file)
fprintf(Loading geo files from cache ( %s)\n, geoCacheFilename);
%result = load(geoCacheFilename);
%geo = result.geo;
%geoXY = result.geoXY;
%clear result;
else
fprintf(Computing geo data\n);
geo = chrReadBinaryGeo(geoFilepath);
fprintf(Computing geoXY data\n);
tic;
geoXY = geoTransformMeshToXYGrid(geo, xyStep);
toc;
fprintf(Saving geo files to cache ( %s)\n, geoCacheFilename);

Apendice F. Codigos Fuente 165


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

save(geoCacheFilename, geo, geoXY);


end

velocityXYCacheFilename = sprintf( %s/binaries.cache.xy. %s.mat, cacheFolder, settings.name);


if exist(velocityXYCacheFilename, file)
fprintf(Loading velocityXY from cache ( %s)\n, velocityXYCacheFilename);
result = load(velocityXYCacheFilename);
velocityXY = result.velocityXY;
clear result;
else
fprintf(Computing velocity data\n);
tic;
velocityXY = chrReadVelocity2D(filepaths, geo, geoXY);
toc;
fprintf(Saving velocityXY to cache ( %s)\n, velocityXYCacheFilename);
save(velocityXYCacheFilename, velocityXY);
end

if PLOT
%magnitude = sqrt(sum(binariesXY{1}.^2, 3));
reynoldsVel = computeReynoldsTensor(velocityXY.u);
varVel = std(velocityXY.u, 0, 3).^2;
rmsVel = computeRMS(velocityXY.u);
meanVel = mean(velocityXY.u,3);

figure;
subplot(121);
pcolor(x,y,reynoldsVel);
hold on;
axis equal;
xlim([geoXY.bounds.minX geoXY.bounds.maxX]);
ylim([geoXY.bounds.minY geoXY.bounds.maxY]);
shading interp;
colorbar;
title(sprintf(Reynolds Long. Tensor over %s Dataset, settings.name));

subplot(122);
pcolor(x,y,varVel);
hold on;
axis equal;
xlim([geoXY.bounds.minX geoXY.bounds.maxX]);
ylim([geoXY.bounds.minY geoXY.bounds.maxY]);
shading interp;
colorbar;
title(sprintf(Variance over %s Dataset, settings.name));

figure;
subplot(121);
pcolor(x,y,rmsVel);
hold on;
axis equal;
xlim([geoXY.bounds.minX geoXY.bounds.maxX]);
ylim([geoXY.bounds.minY geoXY.bounds.maxY]);
shading interp;
colorbar;
title(sprintf(Root Mean Square over %s Dataset, settings.name));

subplot(122);
pcolor(x,y,meanVel);
hold on;
axis equal;
xlim([geoXY.bounds.minX geoXY.bounds.maxX]);
ylim([geoXY.bounds.minY geoXY.bounds.maxY]);
shading interp;
colorbar;
title(sprintf(Mean over %s Dataset, settings.name));
end

Apendice F. Codigos Fuente 166


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.3.4. computeReynoldsTensor.m

function [ UxUx ] = computeReynoldsTensor( velocityXY )


% compute <ux ux> or <uy uy> (use u for <ux ux> and v for <uy uy>)
% compute <ux ux> = <uxux> - <ux><ux> (cell to cell operations)
% notation: U means u. u means u.
% then: <UxUx> = <uxux> - <ux>.*<ux>

uxux = mean(velocityXY.^2, 3);


ux = mean(velocityXY, 3);
UxUx = uxux - ux.*ux;
end

F.3.5. computeRMS.m

function [ rms ] = computeRMS( velocityXY )


rms = sqrt(mean(velocityXY.^2, 3));
end

F.3.6. selectIntegrationCoordinates.m

function [xIntegration, yIntegration] = selectIntegrationCoordinates(geoXY, clipArea, integrationArea)


xValues = geoXY.gridValues.x(find(geoXY.gridValues.x >= clipArea.x1 & geoXY.gridValues.x <= clipArea.x2
));
yValues = geoXY.gridValues.y(find(geoXY.gridValues.y >= clipArea.y1 & geoXY.gridValues.y <= clipArea.y2
));

xIntegration = find(xValues >= integrationArea.x1 & xValues <= integrationArea.x2);


yIntegration = find(yValues >= integrationArea.y1 & yValues <= integrationArea.y2);
end

F.4. Simulacion en Code Saturne


F.4.1. usini1.f90

!-------------------------------------------------------------------------------
! Code_Saturne version 2.0.2
! --------------------------
! This file is part of the Code_Saturne Kernel, element of the
! Code_Saturne CFD tool.
! Copyright (C) 1998-2009 EDF S.A., France
! contact: saturne-support@edf.fr
! The Code_Saturne Kernel is free software; you can redistribute it
! and/or modify it under the terms of the GNU General Public License
! as published by the Free Software Foundation; either version 2 of
! the License, or (at your option) any later version.
! The Code_Saturne Kernel is distributed in the hope that it will be
! useful, but WITHOUT ANY WARRANTY; without even the implied warranty
! of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
! You should have received a copy of the GNU General Public License
! along with the Code_Saturne Kernel; if not, write to the
! Free Software Foundation, Inc.,
! 51 Franklin St, Fifth Floor,
! Boston, MA 02110-1301 USA
!-------------------------------------------------------------------------------
! Purpose:
! -------

Apendice F. Codigos Fuente 167


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! User subroutines for input of calculation parameters (Fortran commons).


! These subroutines are called in all cases.
! If the Code_Saturne GUI is used, this file is not required (but may be
! used to override parameters entered through the GUI, and to set
! parameters not accessible through the GUI).
! Several routines are present in the file, each destined to defined
! specific parameters.
! To modify the default value of parameters which do not appear in the
! examples provided, code should be placed as follows:
! - usipsu for numerical and physical options
! - usipes for input-output related options
! As a convention, "specific physics" defers to the following modules only:
! pulverized coal, gas combustion, electric arcs.
!===============================================================================
subroutine usipph &
!================
( nphmax, nphas , iihmpu, nfecra , iturb , icp , iverif )
!===============================================================================
! Purpose:
! --------
! User subroutine for input of parameters depending on the number of phases.
!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! nphmax ! i ! <-- ! maximum number of phases !
! nphas ! i ! <-- ! number of active phases !
! iihmpu ! i ! <-- ! indicates if the XML file from the GUI is !
! ! ! ! used (1: yes, 0: no) !
! nfecra ! i ! <-- ! Fortran unit number for standard output !
! iturb(nphmax) ! ia ! <-> ! turbulence model !
! icp(nphmax) ! ia ! <-> ! flag for uniform Cp or not !
! iverif ! i ! <-- ! flag for elementary tests !
!__________________!____!_____!________________________________________________!
! Type: i (integer), r (real), s (string), a (array), l (logical),
! and composite types (ex: ra real array)
! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================
implicit none
! Arguments
integer nphmax, nphas, iihmpu, nfecra
integer iturb(nphmax), icp(nphmax)
integer iverif

! Local variables
integer iphas
!===============================================================================
! --- Turbulence (for each phase)
! 0...Laminar
! 10...Mixing length
! 20...k-epsilon
! 21...k-epsilon (linear production)
! 30...Rij-epsilon, (standard LRR)
! 31...Rij-epsilon (SSG)
! 40...LES (Smagorinsky)
! 41...LES (Dynamic)
! 42...LES (WALE)
! 50...v2f (phi-model)
! 60...k-omega SST
! For 10, contact the development team before use

iphas = 1
iturb(iphas) = 0

! --- Variable specific heat (ICP=1) or not (ICP=0)


! for each phase IPHAS
! For these specific physics, ICP MUST NOT BE MODIFIED here, and the
! following options are forced:
! coal and combustion: constant CP constant;

Apendice F. Codigos Fuente 168


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! electric arcs: variable CP.

! Caution: complete usphyv with the law defining Cp


! ========= if and only if variable Cp has been selected here
! (with icp(iphas)=1)
iphas = 1
icp(iphas) = 0

return
end subroutine

!===============================================================================
subroutine usinsc &
!================
( iihmpu, nfecra , nscaus , iverif )
!===============================================================================
! Purpose:
! ------
! User subroutine for input of the number of user scalars.
!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! iihmpu ! i ! <-- ! indicates if the XML file from the GUI is !
! ! ! ! used (1: yes, 0: no) !
! nfecra ! i ! <-- ! Fortran unit number for standard output !
! nscaus ! i ! <-> ! number of user scalars !
! iverif ! i ! <-- ! flag for elementary tests !
!__________________!____!_____!________________________________________________!
! Type: i (integer), r (real), s (string), a (array), l (logical),
! and composite types (ex: ra real array)
! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================
implicit none
! Arguments
integer iihmpu, nfecra
integer nscaus
integer iverif
! Local variables
!===============================================================================
! --- Number of USER scalars (thermal or not, and whatever their carrier phase).
! These scalars come in addition to the following "basic" scalars
! (which are naturally included in the model):
! - pressure
! - turbulent variables
! - nscapp scalars introduced by an active combustion, coal,
! or electric arc module.
! Thus, for a calculation with no specific physics, the user scalars
! may for example be:
! - temperature or enthalpy,
! - mass fractions of transported scalars
! - the variance of another user scalar
! The maximum number of scalars is defined by nscamx in paramx.h;
! it is the maximum admissible value for: nscaus + nscapp.
! Set nscaus = 0 if there is no user scalar.
nscaus = 1

return
end subroutine

!===============================================================================
subroutine usipsc &
!================
( nscmax, nscaus, iihmpu, nfecra, iscavr, ivisls , iverif )
!===============================================================================
! Purpose:
! -------
! User subroutine for the input of parameters depending on the
! number of user scalars.

Apendice F. Codigos Fuente 169


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! nscmax ! i ! <-- ! maximum number of scalars !
! nscaus ! i ! <-- ! number of user scalars !
! iihmpu ! i ! <-- ! indicates if the XML file from the GUI is !
! ! ! ! used (1: yes, 0: no) !
! nfecra ! i ! <-- ! Fortran unit number for standard output !
! iscavr(nscmax) ! ia ! <-- ! associated scalar number for variance scalars !
! ivisls(nscmax) ! ia ! <-> ! uniform scalar diffusivity flag !
! iverif ! i ! <-- ! flag for elementary tests !
!__________________!____!_____!________________________________________________!
! Type: i (integer), r (real), s (string), a (array), l (logical),
! and composite types (ex: ra real array)
! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================
implicit none
! Arguments
integer nscmax, nscaus, iihmpu, nfecra
integer iscavr(nscmax), ivisls(nscmax)
integer iverif
! Local variables
integer iutile, iscal
!===============================================================================
! --- Variance of a USER scalar:
! If we wish a user scalar j to represent the variance of a
! user scalar k, we set
! iscavr(j) = k.
! The values taken by iscavr are thus naturally greater or equal to 1
! and less than or equal to the total number of scalars.
! So, if we set iscavr(j) = k, we must have
! 0 < j < nscaus+1, 0< k < nscaus+1 and j different from k.
! For example for user scalar 3 to be the variance of user scalar 3,
! we set:
! iscavr(3) = 2
! with nscaus at least equal to 3.
! Do not intervene if you do not wish to explicitly include the
! variance of a user scalar in the simulation.
! For non-user scalars relative to specific physics (coal, combustion,
! electric arcs: see usppmo) implicitly defined in the model,
! the corresponding information is given automatically, and
! iscavr should not be modified.
! --- Variable diffusivity (ivisls=1) or constant diffusivity (ivisls=0) for
! each USER scalar, EXCEPT those which represent the variance
! of another.
! For user scalars iscal which represent the variance of another user
! scalar, we do not set ivisls(iscal) here.
! This is the purpose of the test on iscavr(ISCAL) in the example below.
! Indeed, the diffusivity of the variance of a scalar is assumed to
! have the same behavior as the diffusivity of this scalar.
! For non-user scalars relative to specific physics (coal, combustion,
! electric arcs: see usppmo) implicitly defined in the model,
! the corresponding information is given automatically, and
! ivisls should not be modified here.
! Caution: complete usphyv with the law defining the diffusivity
! ========= if and only if ivisls = 1 has been set here.
do iscal = 1, nscaus
! For user scalars which do not represent the variance of another scalar
if (iscavr(iscal).le.0) then
ivisls(iscal) = 0
endif
enddo

return
end subroutine

!===============================================================================
subroutine usipgl &

Apendice F. Codigos Fuente 170


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

!================
( nphmax, nesmax, &
iespre, iesder, iescor, iestot, &
nphas , iihmpu, nfecra, &
idtvar, ipucou, iphydr, ialgce , iescal , iverif )
!===============================================================================
! Purpose:
! -------
! User subroutine for the setting of global parameters.
!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! nphmax ! i ! <-- ! maximum number of phases !
! nesmax ! i ! <-- ! maximum number of error estimators per phase !
! iespre ! i ! <-- ! number of the prediction error estimator !
! iesder ! i ! <-- ! number of the derivative error estimator !
! iescor ! i ! <-- ! number of the correction error estimator !
! iestot ! i ! <-- ! number of the total error estimator !
! nphas ! i ! <-- ! number of active phases !
! iihmpu ! i ! <-- ! indicates if the XML file from the GUI is !
! ! ! ! used (1: yes, 0: no) !
! nfecra ! i ! <-- ! Fortran unit number for standard output !
! idtvar ! i ! --> ! variable time step flag !
! ipucou ! i ! --> ! reinforced u-p coupling flag !
! iphydr ! i ! --> ! flag for handling of the equilibrium between !
! ! ! ! the pressure gradient and the gravity and !
! ! ! ! head-loss terms !
! ialgce ! i ! <-- ! option for the method of calculation of !
! ! ! ! cell centers !
! iescal ! ia ! <-- ! flag for activation of error estimators for !
! (nesmax,nphmax) ! ! ! Navier-Stokes !
! iverif ! i ! <-- ! flag for elementary tests !
!__________________!____!_____!________________________________________________!
! Type: i (integer), r (real), s (string), a (array), l (logical),
! and composite types (ex: ra real array)
! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================

implicit none
! Arguments
integer nphmax, nesmax
integer iespre, iesder, iescor, iestot
integer nphas , iihmpu, nfecra
integer idtvar, ipucou, iphydr
integer iescal(nesmax,nphmax)
integer iverif
! Local variables
integer iphas, ialgce
!===============================================================================
! --- Time step (0 : uniform and constant
! 1 : variable in time, uniform in space
! 2 : variable in time and space
! -1 : steady algorithm)
idtvar = 0

! --- Velocity/pressure coupling (0 : classical algorithm,


! 1 : transient coupling)
! Only in single-phase
ipucou = 0

! --- Handling of hydrostatic pressure


! (0 : usual algorithm
! 1 : specific handling)
! Only in single-phase
iphydr = 0

Apendice F. Codigos Fuente 171


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! --- Estimators for Navier-Stokes (non-frozen velocity field)


! We recommend running a calculation restart on a few time steps
! with the activation of the most interesting of those.
! (=2 to activate, =0 to deactivate).
iphas = 1
iescal(iescor,iphas) = 0
iescal(iestot,iphas) = 0

return
end subroutine

!===============================================================================
subroutine usipsu &
!================
( nmodpp , iverif )
!===============================================================================
! Purpose:
! -------
! User subroutine for the input of additional user parameters.
!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! nmodpp ! i ! <-- ! number of active specific physics models !
! iverif ! i ! <-- ! flag for elementary tests !
!__________________!____!_____!________________________________________________!
! Type: i (integer), r (real), s (string), a (array), l (logical),
! and composite types (ex: ra real array)
! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================
implicit none
include "paramx.h"
include "cstnum.h"
include "dimens.h"
include "numvar.h"
include "optcal.h"
include "cstphy.h"
include "entsor.h"
include "vector.h"
include "parall.h"
include "period.h"
include "ihmpre.h"
include "ppppar.h"
include "ppthch.h"
include "ppincl.h"
include "coincl.h"
include "cpincl.h"
include "elincl.h"
!===============================================================================
! Arguments
integer nmodpp
integer iverif
! Local variables
integer iphas, iutile, ii, jj, imom
!===============================================================================

!===============================================================================
! This subroutine allows setting parameters
! which do not already appear in the other subroutines of this file.
! It is possible to add or remove parameters.
! The number of physical properties and variables is known here.
!===============================================================================
! Calculation options (optcal.h)
! ==============================
! --- Calculation restart: isuite (= 1) or not (0)
! In case of restart, read auxiliary restart file ileaux (= 1) or not (0).
isuite = 1
ileaux = 1

Apendice F. Codigos Fuente 172


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! --- Reference time step


! The example given below is probably not adapted to your case.
! the dt variable should complain with the {{CourantFriedrichsLewy (CFL) condition in order to avoid
divergency.
! u*dt/dx <= C
! being C an dimensionless constant depending on the solver algorithm.
!
! the condition can be also written as
! dt/(dx^2*re) <= C2
dtref = 0.061d0

! --- Duration
! ntmabs = absolute number of the last time step required
! if we have already run 10 time steps and want to
! run 10 more, ntmabs must be set to 10 + 10 = 20
! ntmabs = total_time / dtref
ntmabs = 16000

iphas = 1
iscalt(iphas) = -1

! --- Calculation (restart) with frozen velocity field (1 yes, 0 no)


iccvfg = 0

! --- Vortex method for inlet conditions in L.E.S.


! (0: not activated, 1: activated)
! The vortex method only regards the L.E.S. models
! and is only valid with one phase.
! To use the vortex method, edit the usvort.f90 user file.

! --- Convective scheme

! blencv = 0 for upwind (order 1 in space, "stable but diffusive")


! = 1 for centered/second order (order 2 in space)
! we may use intermediate real values.
! Here we choose:
! for the velocity of phase 1 and user scalars:
! an upwind-centered scheme with 100 % centering (blencv=1)
! for other variables
! the default code value (upwind standard, centered in LES)

! Specifically, for user scalars


! if we suspect an excessive level of numerical diffusion on
! a variable ivar representing a user scalar
! iscal (with ivar=isca(iscal)), it may be useful to set
! blencv(ivar) = 1.0d0 to use a second-order scheme in space for
! convection. For temperature or enthalpy in particular, we
! may thus choose in this case:
! blencv(isca(iscalt(iphas))) = 1.0d0

! For non-user scalars relative to specific physics (coal, combustion,


! electric arcs: see usppmo) implicitly defined by the model,
! the corresponding information is set automatically elsewhere:
! we do not modify blencv here.
iphas = 1
blencv(iu(iphas)) = 1.0d0
blencv(iv(iphas)) = 1.0d0
blencv(iw(iphas)) = 1.0d0
if (nscaus.ge.1) then
do ii = 1, nscaus
! first order diffusivity : blencv(isca(ii)) = 0.0d0
! second order diffusivity : blencv(isca(ii)) = 1.0d0
blencv(isca(ii)) = 0.0d0
idiff(isca(ii)) = 0.0d0
enddo
endif

! --- Linear solver parameters (for each unknown)


! iresol = -1: default

Apendice F. Codigos Fuente 173


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! iresol = 1000*ipol +j: ipol is the degree of the Neumann polynomial


! used for preconditioning,
! j = 0: conjugate gradient,
! j = 1: Jacobi
! j = 2: bi-CgStab
! nitmax: maximum number of iterations for each unknown ivar
! epsilo: relative precision for the solution of the linear system.

! --- Algebraic multigrid parameters

! imgr = 0: no multigrid
! imgr = 1: algebraic multigrid
! Only available for pressure and purely diffusive variables.
imgr = 0

!=========================================================================
! Physical constants (cstphy.h)
! =============================

! --- gravity (g in m/s2, with the sign in the calculation coordinate axes).

gx = 0.d0
gy = 0.d0
gz = 0.d0

! --- Reference fluid properties (for each phase)

! ro0 : density in kg/m3


! viscl0 : dynamic viscosity in kg/(m s)
! cp0 : specific heat in J/(degres kg)
! t0 : reference temperature in Kelvin
! p0 : total reference pressure in Pascal
! the calculation is based on a
! reduced pressure P*=Ptot-ro0*g.(x-xref)
! (except in compressible case)
! xyzp0(3,.) : coordinates of the reference point for
! the total pressure (where it is equal to p0)

! In general, it is not necessary to furnish a reference point xyz0.


! If there are outlets, the code will take the center of the
! reference outlet face.
! On the other hand, if we plan to explicitly fix Dirichlet conditions
! for pressure, it is better to indicate to which reference the
! values relate (for a better resolution of reduced pressure).

! Other properties are given by default in all cases.

! Nonetheless, we may note that:

! In the standard case (no gas combustion, coal, electric arcs,


! compressibility):
! ---------------------
! ro0, viscl0 and cp0
! are useful and represent either the fluid properties if they
! are constant, either simple mean values for the initialization
! if properties are variable and defined in usphyv.
! t0 is not useful
! p0 is useful but is not used in an equation of state. p0
! is a reference value for the incompressible solver
! which will serve to set the (possible) domain outlet pressure.
! We may also take it as 0 or as a physical value in Pascals.

! With compressibility:
! ---------------------
! ro0 is not useful, stricto sensu; nonetheless, as experience
! shows that users often use this variable, it is required
! to assign to it a strictly positive value (for example,
! an initial value).
! viscl0 is useful and represents the molecular dynamic viscosity,

Apendice F. Codigos Fuente 174


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! when it is constant, or a value which will be used during


! initializations (or in inlet turbulence conditions,
! depending on the user choice.
! cp0 is indispensable: it is the heat capacity, assumed constant
! in the thermodynamics available by default
! t0 is indispensable and must be in Kelvin (> 0).
! p0 is indispensable and must be in Pascal (> 0).
! With the thermodynamic law available by default,
! t0 and p0 are used for the initialization of the density.
! xyzp0 is not useful because the pressure variable directly
! represents the total pressure.

iphas = 1
ro0(iphas) = 1.d0 !calculo adimensional
viscl0(iphas) = 1.d0/235.D0 !1/Reynolds
cp0(iphas) = 1.d0
t0(iphas) = 1.d0
p0(iphas) = 0.d0

! We only specify XYZ0 if we explicitely fix Dirichlet conditions


! for the pressure.
! xyzp0(1,iphas) = 0.d0
! xyzp0(2,iphas) = 0.d0
! xyzp0(3,iphas) = 0.d0

! --- irovar, ivivar: density and viscosity constant or not ?

! When a specific physics module is active


! (coal, combustion, electric arcs, compressible: see usppmo)
! we DO NOT set variables irovar and ivivar here, as
! they are defined automatically.
! Nonetheless, for the compressible case, ivivar may be modified
! in the uscfx1 user subroutine.

! When no specific physics module is active, it is necessary to


! specify is the density and the molecular viscosity
! are constant (irovar=0, ivivar=0)
! or variable (irovar=1, ivivar=1)

! if they are variable, the law must be defined in usphyv;


! if they are constant, they take values ro0 and viscl0.

! as an example, we assume below that they are constant.

iphas = 1
irovar(iphas) = 0
ivivar(iphas) = 0

! --- Reference diffusivity visls0 in kg/(m s) for each


! USER scalar except those which represent the variance of another.

! For non-user scalars relative to specific physics (coal, combustion,


! electric arcs: see usppmo) implicitly defined in the model,
! the information is given automatically elsewhere:
! we do not modify visls0 here.

! For user scalars JJ which represent the variance of another user


! scalar, we do not define visls0(jj) here.
! This is the purpose of the test on iscavr(jj) in the example below.
! Indeed the diffusivity of the variance of a scalar is assumed
! identical to that scalars diffusivity.

! When no specific physics has been activated


! (coal, combustion, electric arcs) and if a user scalar represents
! the temperature or enthalpy:
! visls0(iscalt(iphas)) = Lambda/Cp

Apendice F. Codigos Fuente 175


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! Here, as an example, we assign to viscl0 the viscosity of the


! carrier phase, which is fitting for passive tracers which
! follow the fluid.

if (nscaus.gt.0) then
! We loop on user scalars:
do jj = 1, nscaus
! For scalars which are not variances
if (iscavr(jj).le.0) then
! We define the diffusivity
visls0(jj) = viscl0(iphsca(jj))
endif
enddo
endif

! --- Reference velocity for turbulence initialization (m2/s)


! (useful only with turbulence)
iphas = 1
uref(iphas) = 1.d0

! --- Definition of moments


! (at the most nbmomx moments, correlations of maximum order ndgmox)

! We calculate temporal means of the type <f1*f2*f3*...*fn>


! The fis are cell-defined variables (arrays rtp and propce).

! idfmom(i,imom) ientifies the variable fi of moment imom


! if idfmom > 0 it is a resolved variable (rtp)
! if idfmom < 0 it is an auxiliary variable (propce)
! imoold(imom) defined in the case of a restart the number, in the
! previous calculation, of the moment to use to initialize moment
! imom of the new calculation (by default imoold(imom)=imom).
! Value -1 indicates the we must reinitialize moment imom.
! ntdmom(imom) defined the time step at which the moment calculation
! is started.

! We give below the example of the calculation of moments <u> and <rho u v>
! the moment <u> is reread in the restart file if we are restarting,
! the moment <rho u v> is reinitialized to zero.
! Moment <u> is calculated starting from time step 1000
! Moment <rho u v> is calculated from time step 10000.

! The test on iutile allows deactivation of the instructions


! (which are only given as an example).

iutile = 0
if (iutile.eq.1) then

! First moment: <u>


imom = 1
iphas = 1
idfmom(1,imom) = iu(iphas)
ntdmom(imom) = 1000
! Second moment: <rho u v>
imom = 2
iphas = 1
idfmom(1,imom) = -irom(iphas)
idfmom(2,imom) = iu(iphas)
idfmom(3,imom) = iv(iphas)
imoold(imom) = -1
ntdmom(imom) = 10000

endif

return
end subroutine

!===============================================================================

Apendice F. Codigos Fuente 176


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

subroutine usipes &


!================
( nmodpp , iverif )
!===============================================================================
! Purpose:
! --------
! User subroutine for the input of additional user parameters for
! input/output.
!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! nmodpp ! i ! <-- ! number of active specific physics models !
! iverif ! i ! <-- ! flag for elementary tests !
!__________________!____!_____!________________________________________________!

! Type: i (integer), r (real), s (string), a (array), l (logical),


! and composite types (ex: ra real array)
! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================
implicit none
include "paramx.h"
include "cstnum.h"
include "dimens.h"
include "numvar.h"
include "optcal.h"
include "cstphy.h"
include "entsor.h"
include "vector.h"
include "parall.h"
include "period.h"
include "ihmpre.h"
include "ppppar.h"
include "ppthch.h"
include "ppincl.h"
!===============================================================================
! Arguments
integer nmodpp
integer iverif
! Local variables
integer ii, iphas, ipp, imom, iutile

! Local variables - LFD


TYPE probes_area
double precision xStart
double precision yStart
double precision xEnd
double precision yEnd
double precision separation
END TYPE

TYPE probes_line
double precision xStart
double precision yStart
double precision xEnd
double precision yEnd
double precision separation
END TYPE

double precision xProbe, yProbe, xSeparationProbe, ySeparationProbe


integer iProbe, iProbeLine, iProbeArea

TYPE(probes_line) probesLines(0)
TYPE(probes_area) probesAreas(2)

! Should define TYPE(probes_area) probesAreas(2)


probesAreas(1) %xStart = 0.0
probesAreas(1) %xEnd = 20.0
probesAreas(1) %yStart = 1.0

Apendice F. Codigos Fuente 177


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

probesAreas(1) %yEnd = 1.0


probesAreas(1) %separation = 0.5
probesAreas(2) %xStart = 0.0
probesAreas(2) %yStart = -1.0
probesAreas(2) %xEnd = 20.0
probesAreas(2) %yEnd = -1.0
probesAreas(2) %separation = 0.5
!===============================================================================

!===============================================================================
! 1. Input-output (entsor.h)
!===============================================================================
! --- write auxiliary restart file iecaux = 1 yes, 0 no
iecaux = 1

! Frequency of log output


ntlist = 25

! --- post-processing output


! ichrvl: post-processing of the fluid domain (yes 1/no 0)
! ichrbo: post-processing of the domain boundary (yes 1/no 0)
! ichrsy: post-processing of zones coupled with SYRTHES (yes 1/ no 0)
! ichrmd: indicates if the meshes output are:
! 0: fixed, 1: deformable with constant connectivity, ...

! fmtchr: output format, amid


! EnSight Gold, MED, or CGNS
! optchr: options associated with the output format, separated by
! commas, from the following list:
! text (text format, for EnSight)
! binary (binary format, default choice)
! ...
ichrvl = 1
ichrbo = 0
ichrsy = 0
ichrmd = 0
fmtchr = EnSight Gold
optchr = binary

! --- chronological output step


! (-1: only one valua at calculation end)
! (strictly positive valeu: output periodicity)
ntchr = 10

! --- history output step


nthist = 1
ntsuit = 100

! --- Number of monitoring points (probes) and their positions


! (limited to ncaptm=100)

! nthsav: saving period the chronological record files (they are first stored in a temporary file and then
saved every nthsav time step)
! = 0: by default (4 times during a calculation)
! = -1: saving at the end of the calculation
! > 0: period (every nthsav time step)
nthsav = 1

iProbe = 0
do iProbeLine = 1, size(probesLines), 1
ySeparationProbe = sin(atan((probesLines(iProbeLine) %yEnd - probesLines(iProbeLine) %yStart)/ &
(probesLines(iProbeLine) %xEnd - probesLines(iProbeLine) %xStart))) &
*probesLines(iProbeLine) %separation
xSeparationProbe = cos(atan((probesLines(iProbeLine) %yEnd - probesLines(iProbeLine) %yStart)/ &
(probesLines(iProbeLine) %xEnd - probesLines(iProbeLine) %xStart))) &
*probesLines(iProbeLine) %separation

xProbe = probesLines(iProbeLine) %xStart

Apendice F. Codigos Fuente 178


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

yProbe = probesLines(iProbeLine) %yStart


do while ((((ySeparationProbe.ge.0).and.(yProbe.le.probesLines(iProbeLine) %yEnd)) &
.or.((ySeparationProbe.lt.0).and.(yProbe.ge.probesLines(iProbeLine) %yEnd))) &
.and.(((xSeparationProbe.ge.0).and.(xProbe.le.probesLines(iProbeLine) %xEnd)) &
.or.((xSeparationProbe.lt.0).and.(xProbe.ge.probesLines(iProbeLine) %xEnd))))

iProbe = iProbe + 1
xyzcap(1,iProbe) = xProbe
xyzcap(2,iProbe) = yProbe
xyzcap(3,iProbe) = 0.00d0

yProbe = yProbe + ySeparationProbe


xProbe = xProbe + xSeparationProbe
end do
end do

do iProbeArea = 1, size(probesAreas), 1
ySeparationProbe = sign(probesAreas(iProbeArea) %separation, probesAreas(iProbeArea) %yEnd - probesAreas
(iProbeArea) %yStart)
xSeparationProbe = sign(probesAreas(iProbeArea) %separation, probesAreas(iProbeArea) %xEnd - probesAreas
(iProbeArea) %xStart)

xProbe = probesAreas(iProbeArea) %xStart


do while (((xSeparationProbe.ge.0).and.(xProbe.le.probesAreas(iProbeArea) %xEnd)) &
.or.((xSeparationProbe.lt.0).and.(xProbe.ge.probesAreas(iProbeArea) %xEnd)))

yProbe = probesAreas(iProbeArea) %yStart


do while (((ySeparationProbe.ge.0).and.(yProbe.le.probesAreas(iProbeArea) %yEnd)) &
.or.((ySeparationProbe.lt.0).and.(yProbe.ge.probesAreas(iProbeArea) %yEnd)))

iProbe = iProbe + 1
xyzcap(1,iProbe) = xProbe
xyzcap(2,iProbe) = yProbe
xyzcap(3,iProbe) = 0.00d0

yProbe = yProbe + ySeparationProbe


end do
xProbe = xProbe + xSeparationProbe
end do
end do
ncapt = iProbe

! --- current variable


! As for other variables,
! if we do not assign the following array values,
! default values will be used
! nomvar( ) = variable name
! ichrvr( ) = chonological output (yes 1/no 0)
! ilisvr( ) = logging in listing (yes 1/no 0)
! ihisvr( ) = history output (number of probes and their numbers)
! if ihisvr(.,1) = -1, output for all probes
! Note: Only the fist 8 characters of a name will be used in the most
! detailed log.
iphas = 1

!ex ! pressure variable


ipp = ipprtp(ipr (iphas))
nomvar(ipp) = Pressure
ichrvr(ipp) = 1
ilisvr(ipp) = 1
ihisvr(ipp,1) = -1

!ex ! variable v1x


ipp = ipprtp(iu (iphas))
nomvar(ipp) = VelocityX
ichrvr(ipp) = 1
ilisvr(ipp) = 1
ihisvr(ipp,1) = -1

!ex ! v1y variable

Apendice F. Codigos Fuente 179


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

ipp = ipprtp(iv (iphas))


nomvar(ipp) = VelocityY
ichrvr(ipp) = 1
ilisvr(ipp) = 1
ihisvr(ipp,1) = -1

!ex ! v1z variable


ipp = ipprtp(iw (iphas))
nomvar(ipp) = VelocityZ
ichrvr(ipp) = 1
ilisvr(ipp) = 1
ihisvr(ipp,1) = -1

! User scalar variables.


! We may modify here the arrays relative to user scalars, but scalars
! reserved for specific physics are handled automatically. This explains
! the tests on nscaus, which ensure that the targeted scalars are
! truly user scalars.
! By specific physics, we mean only those which are handled in specific
! modules of the code, such as coal, combustion, electric arcs (see usppmo).

if (isca(1).gt.0.and.nscaus.ge.1) then
ipp = ipprtp(isca (1))
nomvar(ipp) = Scalar1
ichrvr(ipp) = 1
ilisvr(ipp) = 1
ihisvr(ipp,1)= -1
endif

! Other variables

iphas = 1

return
end subroutine

!===============================================================================
subroutine ustbtr &
!================
( ncel , ncelet , nfac , nfabor , nnod , &
longia , longra , &
nideve , nituse , nrdeve , nrtuse )
!===============================================================================
! Purpose:
! -------
! User subroutine to define the sizes of macro-arrays ia and ra,
! of user arrays ituser and rtuser,
! of developper arrays idevel and rdevel.
!-------------------------------------------------------------------------------
! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! ncel ! i ! <-- ! number of cells !
! ncelet ! i ! <-- ! number of extended (real + ghost) cells !
! nfac ! i ! <-- ! number of interior faces !
! nfabor ! i ! <-- ! number of boundary faces !
! nnod ! i ! <-- ! number of vertices !
! longia ! i ! --> ! size of array ia !
! longra ! i ! --> ! size of array ra !
! nideve ! i ! --> ! size of array idevel !
! nituse ! i ! --> ! size of array ituser !
! nrdeve ! i ! --> ! size of array rdevel !
! nrtuse ! i ! --> ! size of array rtuser !
!__________________!____!_____!________________________________________________!
! Type: i (integer), r (real), s (string), a (array), l (logical),

Apendice F. Codigos Fuente 180


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! and composite types (ex: ra real array)


! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================
implicit none
! Arguments
integer ncel , ncelet, nfac , nfabor, nnod
integer longia, longra
integer nideve, nituse, nrdeve, nrtuse
!===============================================================================

return
end subroutine

F.4.2. usclim.f90

!-------------------------------------------------------------------------------
! Code_Saturne version 2.0.2
! --------------------------
! This file is part of the Code_Saturne Kernel, element of the
! Code_Saturne CFD tool.
! Copyright (C) 1998-2009 EDF S.A., France
! contact: saturne-support@edf.fr
! The Code_Saturne Kernel is free software; you can redistribute it
! and/or modify it under the terms of the GNU General Public License
! as published by the Free Software Foundation; either version 2 of
! the License, or (at your option) any later version.
! The Code_Saturne Kernel is distributed in the hope that it will be
! useful, but WITHOUT ANY WARRANTY; without even the implied warranty
! of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
! You should have received a copy of the GNU General Public License
! along with the Code_Saturne Kernel; if not, write to the
! Free Software Foundation, Inc.,
! 51 Franklin St, Fifth Floor,
! Boston, MA 02110-1301 USA
!-------------------------------------------------------------------------------
subroutine usclim &
!================
( idbia0 , idbra0 , &
ndim , ncelet , ncel , nfac , nfabor , nfml , nprfml , &
nnod , lndfac , lndfbr , ncelbr , &
nvar , nscal , nphas , &
nideve , nrdeve , nituse , nrtuse , &
ifacel , ifabor , ifmfbr , ifmcel , iprfml , maxelt , lstelt , &
ipnfac , nodfac , ipnfbr , nodfbr , &
icodcl , itrifb , itypfb , &
idevel , ituser , ia , &
xyzcen , surfac , surfbo , cdgfac , cdgfbo , xyznod , volume , &
dt , rtp , rtpa , propce , propfa , propfb , &
coefa , coefb , rcodcl , &
w1 , w2 , w3 , w4 , w5 , w6 , coefu , &
rdevel , rtuser , ra )
!===============================================================================
! Purpose:
! -------
! User subroutine.
! Fill boundary conditions arrays (icodcl, rcodcl) for unknown variables.
! Introduction
! ============
! Here one defines boundary conditions on a per-face basis.
! Boundary faces may be identified using the getfbr subroutine.
! getfbr(string, nelts, eltlst):
! - string is a user-supplied character string containing selection criteria;
! - nelts is set by the subroutine. It is an integer value corresponding to
! the number of boundary faces verifying the selection criteria;
! - lstelt is set by the subroutine. It is an integer array of size nelts
! containing the list of boundary faces verifying the selection criteria.

Apendice F. Codigos Fuente 181


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! string may contain:


! - references to colors (ex.: 1, 8, 26, ...)
! - references to groups (ex.: inlet, group1, ...)
! - geometric criteria (ex. x < 0.1, y >= 0.25, ...)
! These criteria may be combined using logical operators (and, or) and
! parentheses.
! Example: 1 and (group2 or group3) and y < 1 will select boundary faces
! of color 1, belonging to groups group2 or group3 and with face center
! coordinate y less than 1.
! Operators priority, from highest to lowest:
! ( ) > not > and > or > xor
! Similarly, interior faces and cells can be identified using the getfac
! and getcel subroutines (respectively). Their syntax are identical to
! getfbr syntax.
! For a more thorough description of the criteria syntax, it can be referred
! to the user guide.
! Boundary condition types
! ========================
! Boundary conditions may be assigned in two ways.
! For "standard" boundary conditions:
! -----------------------------------
! (inlet, free outlet, wall, symmetry), one defines a code in the itypfb
! array (of dimensions number of boundary faces, number of phases).
! This code will then be used by a non-user subroutine to assign the
! following conditions (scalars in particular will receive the conditions
! of the phase to which they are assigned). Thus:

! Code | Boundary type


! --------------------------
! ientre | Inlet
! isolib | Free outlet
! isymet | Symmetry
! iparoi | Wall (smooth)
! iparug | Rough wall

! These integers are defined elsewhere (in paramx.h header).


! Their value is greater than or equal to 1 and less than or equal to
! ntypmx (value fixed in paramx.h)

! In addition, some values must be defined:

! - Inlet (more precisely, inlet/outlet with prescribed flow, as the flow


! may be prescribed as an outflow):
! -> Dirichlet conditions on variables other than pressure are mandatory
! if the flow is incoming, optional if the flow is outgoing (the code
! assigns zero flux if no Dirichlet is specified); thus,
! at face ifac, for the variable ivar: rcodcl(ifac, ivar, 1)

! - Smooth wall: (= impermeable solid, with smooth friction)


! -> Velocity value for sliding wall if applicable
! at face ifac, rcodcl(ifac, iu, 1)
! rcodcl(ifac, iv, 1)
! rcodcl(ifac, iw, 1)
! -> Specific code and prescribed temperature value at wall if applicable:
! at face ifac, icodcl(ifac, ivar) = 5
! rcodcl(ifac, ivar, 1) = prescribed temperature
! -> Specific code and prescribed flux value at wall if applicable:
! at face ifac, icodcl(ifac, ivar) = 3
! rcodcl(ifac, ivar, 3) = prescribed flux

! Note that the default condition for scalars (other than k and epsilon)
! is homogeneous Neumann.

! - Rough wall: (= impermeable solid, with rough friction)


! -> Velocity value for sliding wall if applicable
! at face ifac, rcodcl(ifac, iu, 1)
! rcodcl(ifac, iv, 1)
! rcodcl(ifac, iw, 1)
! -> Value of the dynamic roughness height to specify in
! rcodcl(ifac, iu, 3)

Apendice F. Codigos Fuente 182


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! -> Value of the scalar roughness height (if required) to specify in


! rcodcl(ifac, iv, 3) (values for iw are not used)
! -> Specific code and prescribed temperature value at wall if applicable:
! at face ifac, icodcl(ifac, ivar) = 6
! rcodcl(ifac, ivar, 1) = prescribed temperature
! -> Specific code and prescribed flux value at rough wall, if applicable:
! at face ifac, icodcl(ifac, ivar) = 3
! rcodcl(ifac, ivar, 3) = prescribed flux
! Note that the default condition for scalars (other than k and epsilon)
! is homogeneous Neumann.

! - Symmetry (= slip wall):


! -> Nothing to specify

! - Free outlet (more precisely free inlet/outlet with prescribed pressure)


! -> Nothing to prescribe for pressure and velocity. For scalars and
! turbulent values, a Dirichlet value may optionally be specified.
! The behavior is as follows:
! * pressure is always handled as a Dirichlet condition
! * if the mass flow is inflowing:
! one retains the velocity at infinity
! Dirichlet condition for scalars and turbulent values
! (or zero flux if the user has not specified a
! Dirichlet value)
! if the mass flow is outflowing:
! one prescribes zero flux on the velocity, the scalars,
! and turbulent values
! Note that the pressure will be reset to p0 on the first free outlet
! face found

! For "non-standard" conditions:


! ------------------------------
! Other than (inlet, free outlet, wall, symmetry), one defines
! - on one hand, for each face:
! -> an admissible itypfb value (i.e. greater than or equal to 1 and
! less than or equal to ntypmx; see its value in paramx.h).
! The values predefined in paramx.h:
! ientre, isolib, isymet, iparoi, iparug are in this range,
! and it is preferable not to assign one of these integers to itypfb
! randomly or in an inconsiderate manner. To avoid this, one may use
! iindef if one wish to avoid checking values in paramx.h. iindef
! is an admissible value to which no predefined boundary condition
! is attached.
! Note that the itypfb array is reinitialized at each time step to
! the non-admissible value of 0. If one forgets to modify typfb for
! a given face, the code will stop.
! - and on the other hand, for each face and each variable:
! -> a code icodcl(ifac, ivar)
! -> three real values rcodcl(ifac, ivar, 1)
! rcodcl(ifac, ivar, 2)
! rcodcl(ifac, ivar, 3)
! The value of icodcl is taken from the following:
! 1: Dirichlet (usable for any variable)
! 3: Neumann (usable for any variable)
! 4: Symmetry (usable only for the velocity and components of
! the Rij tensor)
! 5: Smooth wall (usable for any variable except for pressure)
! 6: Rough wall (usable for any variable except for pressure)
! 9: Free outlet (usable only for velocity)
! The values of the 3 rcodcl components are:
! rcodcl(ifac, ivar, 1):
! Dirichlet for the variable if icodcl(ifac, ivar) = 1
! Wall value (sliding velocity, temp) if icodcl(ifac, ivar) = 5
! The dimension of rcodcl(ifac, ivar, 1) is that of the
! resolved variable: ex U (velocity in m/s),
! T (temperature in degrees)
! H (enthalpy in J/kg)
! F (passive scalar in -)
! rcodcl(ifac, ivar, 2):
! "exterior" exchange coefficient (between the prescribed value

Apendice F. Codigos Fuente 183


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! and the value at the domain boundary)


! rinfin = infinite by default
! For velocities U, in kg/(m2 s):
! rcodcl(ifac, ivar, 2) = (viscl+visct) / d
! For the pressure P, in s/m:
! rcodcl(ifac, ivar, 2) = dt / d
! For temperatures T, in Watt/(m2 degres):
! rcodcl(ifac, ivar, 2) = Cp*(viscls+visct/sigmas) / d
! For enthalpies H, in kg /(m2 s):
! rcodcl(ifac, ivar, 2) = (viscls+visct/sigmas) / d
! For other scalars F in:
! rcodcl(ifac, ivar, 2) = (viscls+visct/sigmas) / d
! (d has the dimension of a distance in m)
!
! rcodcl(ifac, ivar, 3) if icodcl(ifac, ivar) <> 6:
! Flux density (< 0 if gain, n outwards-facing normal)
! if icodcl(ifac, ivar)= 3
! For velocities U, in kg/(m s2) = J:
! rcodcl(ifac, ivar, 3) = -(viscl+visct) * (grad U).n
! For pressure P, in kg/(m2 s):
! rcodcl(ifac, ivar, 3) = -dt * (grad P).n
! For temperatures T, in Watt/m2:
! rcodcl(ifac, ivar, 3) = -Cp*(viscls+visct/sigmas) * (grad T).n
! For enthalpies H, in Watt/m2:
! rcodcl(ifac, ivar, 3) = -(viscls+visct/sigmas) * (grad H).n
! For other scalars F in:
! rcodcl(ifac, ivar, 3) = -(viscls+visct/sigmas) * (grad F).n

! rcodcl(ifac, ivar, 3) if icodcl(ifac, ivar) = 6:


! Roughness for the rough wall law
! For velocities U, dynamic roughness
! rcodcl(ifac, iu, 3) = roughd
! For other scalars, thermal roughness
! rcodcl(ifac, iv, 3) = rought

! Remarks
! =======

! Caution: to prescribe a flux (nonzero) to Rij, the viscosity to take


! into account is viscl even if visct exists
! (visct=rho cmu k2/epsilon)

! One have the ordering array for boundary faces from the previous time
! step (except for the fist one, where itrifb has not been set yet).
! The array of boundary face types itypfb has been reset before
! entering the subroutine.

! Note how to access some variables (for phase iphas


! variable ivar
! scalar iscal):

! Cell values (let iel = ifabor(ifac))

! * Density: propce(iel, ipproc(irom(iphas)))


! * Dynamic molecular viscosity: propce(iel, ipproc(iviscl(iphas)))
! * Turbulent viscosity: propce(iel, ipproc(ivisct(iphas)))
! * Specific heat: propce(iel, ipproc(icp(iphas))
! * Diffusivity(lambda): propce(iel, ipproc(ivisls(iscal)))

! Boundary face values

! * Density: propfb(ifac, ipprob(irom(iphas)))


! * Mass flux (for convecting ivar): propfb(ifac, ipprob(ifluma(ivar)))

! * For other values: take as an approximation the value in the adjacent cell
! i.e. as above with iel = ifabor(ifac).

!-------------------------------------------------------------------------------

Apendice F. Codigos Fuente 184


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! Arguments
!__________________.____._____.________________________________________________.
! name !type!mode ! role !
!__________________!____!_____!________________________________________________!
! idbia0 ! i ! <-- ! number of first free position in ia !
! idbra0 ! i ! <-- ! number of first free position in ra !
! ndim ! i ! <-- ! spatial dimension !
! ncelet ! i ! <-- ! number of extended (real + ghost) cells !
! ncel ! i ! <-- ! number of cells !
! nfac ! i ! <-- ! number of interior faces !
! nfabor ! i ! <-- ! number of boundary faces !
! nfml ! i ! <-- ! number of families (group classes) !
! nprfml ! i ! <-- ! number of properties per family (group class) !
! nnod ! i ! <-- ! number of vertices !
! lndfac ! i ! <-- ! size of nodfac indexed array !
! lndfbr ! i ! <-- ! size of nodfbr indexed array !
! ncelbr ! i ! <-- ! number of cells with faces on boundary !
! nvar ! i ! <-- ! total number of variables !
! nscal ! i ! <-- ! total number of scalars !
! nphas ! i ! <-- ! number of phases !
! nideve, nrdeve ! i ! <-- ! sizes of idevel and rdevel arrays !
! nituse, nrtuse ! i ! <-- ! sizes of ituser and rtuser arrays !
! ifacel(2, nfac) ! ia ! <-- ! interior faces -> cells connectivity !
! ifabor(nfabor) ! ia ! <-- ! boundary faces -> cells connectivity !
! ifmfbr(nfabor) ! ia ! <-- ! boundary face family numbers !
! ifmcel(ncelet) ! ia ! <-- ! cell family numbers !
! iprfml ! ia ! <-- ! property numbers per family !
! (nfml, nprfml) ! ! ! !
! maxelt ! i ! <-- ! max number of cells and faces (int/boundary) !
! lstelt(maxelt) ! ia ! --- ! work array !
! ipnfac(nfac+1) ! ia ! <-- ! interior faces -> vertices index (optional) !
! nodfac(lndfac) ! ia ! <-- ! interior faces -> vertices list (optional) !
! ipnfbr(nfabor+1) ! ia ! <-- ! boundary faces -> vertices index (optional) !
! nodfbr(lndfbr) ! ia ! <-- ! boundary faces -> vertices list (optional) !
! icodcl ! ia ! --> ! boundary condition code !
! (nfabor, nvar) ! ! ! = 1 -> Dirichlet !
! ! ! ! = 2 -> flux density !
! ! ! ! = 4 -> sliding wall and u.n=0 (velocity) !
! ! ! ! = 5 -> friction and u.n=0 (velocity) !
! ! ! ! = 6 -> roughness and u.n=0 (velocity) !
! ! ! ! = 9 -> free inlet/outlet (velocity) !
! ! ! ! inflowing possibly blocked !
! itrifb ! ia ! <-- ! indirection for boundary faces ordering !
! (nfabor, nphas) ! ! ! !
! itypfb ! ia ! --> ! boundary face types !
! (nfabor, nphas) ! ! ! !
! idevel(nideve) ! ia ! <-> ! integer work array for temporary development !
! ituser(nituse) ! ia ! <-> ! user-reserved integer work array !
! ia(*) ! ia ! --- ! main integer work array !
! xyzcen ! ra ! <-- ! cell centers !
! (ndim, ncelet) ! ! ! !
! surfac ! ra ! <-- ! interior faces surface vectors !
! (ndim, nfac) ! ! ! !
! surfbo ! ra ! <-- ! boundary faces surface vectors !
! (ndim, nfabor) ! ! ! !
! cdgfac ! ra ! <-- ! interior faces centers of gravity !
! (ndim, nfac) ! ! ! !
! cdgfbo ! ra ! <-- ! boundary faces centers of gravity !
! (ndim, nfabor) ! ! ! !
! xyznod ! ra ! <-- ! vertex coordinates (optional) !
! (ndim, nnod) ! ! ! !
! volume(ncelet) ! ra ! <-- ! cell volumes !
! dt(ncelet) ! ra ! <-- ! time step (per cell) !
! rtp, rtpa ! ra ! <-- ! calculated variables at cell centers !
! (ncelet, *) ! ! ! (at current and previous time steps) !
! propce(ncelet, *)! ra ! <-- ! physical properties at cell centers !
! propfa(nfac, *) ! ra ! <-- ! physical properties at interior face centers !
! propfb(nfabor, *)! ra ! <-- ! physical properties at boundary face centers !
! coefa, coefb ! ra ! <-- ! boundary conditions !
! (nfabor, *) ! ! ! !

Apendice F. Codigos Fuente 185


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

! rcodcl ! ra ! --> ! boundary condition values !


! (nfabor,nvar,3) ! ! ! rcodcl(1) = Dirichlet value !
! ! ! ! rcodcl(2) = exterior exchange coefficient !
! ! ! ! (infinite if no exchange) !
! ! ! ! rcodcl(3) = flux density value !
! ! ! ! (negative for gain) in w/m2 or !
! ! ! ! roughness height (m) if icodcl=6 !
! ! ! ! for velocities ( vistl+visct)*gradu !
! ! ! ! for pressure dt*gradp !
! ! ! ! for scalars cp*(viscls+visct/sigmas)*gradt !
! w1,2,3,4,5,6 ! ra ! --- ! work arrays !
! (ncelet) ! ! ! (computation of pressure gradient) !
! coefu ! ra ! --- ! work array !
! (nfabor, 3) ! ! ! (computation of pressure gradient) !
! rdevel(nrdeve) ! ra ! <-> ! real work array for temporary development !
! rtuser(nrtuse) ! ra ! <-> ! user-reserved real work array !
! ra(*) ! ra ! --- ! main real work array !
!__________________!____!_____!________________________________________________!

! Type: i (integer), r (real), s (string), a (array), l (logical),


! and composite types (ex: ra real array)
! mode: <-- input, --> output, <-> modifies data, --- work array
!===============================================================================

implicit none

include "paramx.h"
include "pointe.h"
include "numvar.h"
include "optcal.h"
include "cstphy.h"
include "cstnum.h"
include "entsor.h"
include "parall.h"
include "period.h"
include "ihmpre.h"
!===============================================================================
! Arguments
integer idbia0 , idbra0
integer ndim , ncelet , ncel , nfac , nfabor
integer nfml , nprfml
integer nnod , lndfac , lndfbr , ncelbr
integer nvar , nscal , nphas
integer nideve , nrdeve , nituse , nrtuse

integer ifacel(2,nfac) , ifabor(nfabor)


integer ifmfbr(nfabor) , ifmcel(ncelet)
integer iprfml(nfml,nprfml), maxelt, lstelt(maxelt)
integer ipnfac(nfac+1), nodfac(lndfac)
integer ipnfbr(nfabor+1), nodfbr(lndfbr)
integer icodcl(nfabor,nvar)
integer itrifb(nfabor,nphas), itypfb(nfabor,nphas)
integer idevel(nideve), ituser(nituse), ia(*)

double precision xyzcen(ndim,ncelet)


double precision surfac(ndim,nfac), surfbo(ndim,nfabor)
double precision cdgfac(ndim,nfac), cdgfbo(ndim,nfabor)
double precision xyznod(ndim,nnod), volume(ncelet)
double precision dt(ncelet), rtp(ncelet,*), rtpa(ncelet,*)
double precision propce(ncelet,*)
double precision propfa(nfac,*), propfb(nfabor,*)
double precision coefa(nfabor,*), coefb(nfabor,*)
double precision rcodcl(nfabor,nvar,3)
double precision w1(ncelet),w2(ncelet),w3(ncelet)
double precision w4(ncelet),w5(ncelet),w6(ncelet)
double precision coefu(nfabor,ndim)
double precision rdevel(nrdeve), rtuser(nrtuse), ra(*)

! Local variables
integer idebia, idebra

Apendice F. Codigos Fuente 186


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

integer ifac, iel, ii, ivar, iphas


integer ilelt, nlelt
double precision uref2, d2s3
double precision rhomoy, dh, ustar2
double precision xintur
double precision xkent, xeent

! Local Variables - LFD


double precision alfa, beta
double precision xCentre, yCentre
character*10 sStepNumber
character*10 sProcessorNumber
integer, parameter:: actuatorStartingStep = 7500
real, parameter :: inputVelocity = 1d0
real :: upperActuatorValue, lowerActuatorValue
logical, save:: actuatorValuesInitialized = .false.
!===============================================================================

!===============================================================================
! 1. Initialization
!===============================================================================
if (.not.actuatorValuesInitialized) then
write( sProcessorNumber, (i1) ) irangp
call system("mkfifo semaphore."//sProcessorNumber)
call system("mkfifo act.upper.csv."//sProcessorNumber)
call system("mkfifo act.lower.csv."//sProcessorNumber)

call system("./controller "//sProcessorNumber//" act.upper.csv."//sProcessorNumber &


//" act.lower.csv."//sProcessorNumber//" probes_Scalar1.dat < semaphore."//sProcessorNumber//" &")
open(unit=103, file="semaphore."//sProcessorNumber, action="write")
open(unit=104, file="act.upper.csv."//sProcessorNumber, action="read")
open(unit=105, file="act.lower.csv."//sProcessorNumber, action="read")

actuatorValuesInitialized = .true.
endif

idebia = idbia0
idebra = idbra0

d2s3 = 2.d0/3.d0

!===============================================================================
! 2. Assign boundary conditions to boundary faces here

! One may use selection criteria to filter boundary case subsets


! Loop on faces from a subset
! Set the boundary condition for each face
!===============================================================================

! Code | Boundary type


! --------------------------
! ientre | Inlet
! isolib | Free outlet
! isymet | Symmetry
! iparoi | Wall (smooth)
! iparug | Rough wall

!$PhysicalNames
!1 Layer0
!2 entrada
!3 salida
!4 pared
!5 simetria
!6 interna
!7 actuador
!5 simetria
!$EndPhysicalNames

Apendice F. Codigos Fuente 187


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

!entrada -> ientre


call getfbr(2, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

do iphas = 1, nphas
itypfb(ifac,iphas) = ientre
rcodcl(ifac,iu(iphas),1) = inputVelocity
rcodcl(ifac,iv(iphas),1) = 0.0d0
rcodcl(ifac,iw(iphas),1) = 0.0d0

yCentre = cdgfbo(2,ifac)
do ii = 1, nscal
if(iphsca(ii).eq.iphas) then
if (yCentre.gt.-0.1d0.and.yCentre.lt.0.1d0) then
icodcl(ifac, isca(ii)) = 1
rcodcl(ifac, isca(ii),1) = 1.d0
else
icodcl(ifac, isca(ii)) = 0
rcodcl(ifac, isca(ii),1) = 0.d0
endif
endif
enddo
enddo
enddo

!salida -> isolib


call getfbr(3, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)
iel = ifabor(ifac)
do iphas = 1, nphas
itypfb(ifac,iphas) = isolib

icodcl(ifac,ipr(iphas)) = 1 !dirichlet condition on pressure -> fixed value


icodcl(ifac,iu(iphas)) = 3 !neumann condition on velocity -> fixed gradient
icodcl(ifac,iv(iphas)) = 3
icodcl(ifac,iw(iphas)) = 3

rcodcl(ifac,ipr(iphas),1) = 0.0d0 !dirichlet value fixed to pressure=0


rcodcl(ifac,iu(iphas),3) = 0.0d0 !neumann value fixed to grad(u,normal) = 0
rcodcl(ifac,iv(iphas),3) = 0.0d0
rcodcl(ifac,iw(iphas),3) = 0.0d0
enddo
enddo

!pared -> iparoi


call getfbr(4, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

do iphas = 1, nphas
itypfb(ifac,iphas) = iparoi
enddo
enddo

!simetria -> isymet


call getfbr(5, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

do iphas = 1, nphas
itypfb(ifac,iphas) = isymet
enddo
enddo

if (ntcabs.ge.actuatorStartingStep) then

write(sStepNumber, (i0) ) ntcabs

Apendice F. Codigos Fuente 188


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

write(103,*) sStepNumber

read(104,*) upperActuatorValue
read(105,*) lowerActuatorValue
else
upperActuatorValue = 0
lowerActuatorValue = 0
endif

if (ntmabs.eq.ntcabs) then
close(103)
close(104)
close(105)
endif

!actuador -> iparug


call getfbr(7 and y > 0, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

xCentre = cdgfbo(1,ifac)
yCentre = cdgfbo(2,ifac)
alfa = atan(yCentre / xCentre)
beta = alfa - pi/2.0

do iphas = 1, nphas
itypfb(ifac,iphas) = iparoi
rcodcl(ifac,iu(iphas),1) = upperActuatorValue * cos(beta)
rcodcl(ifac,iv(iphas),1) = upperActuatorValue * sin(beta)
rcodcl(ifac,iw(iphas),1) = 0.0d0
enddo
enddo
call getfbr(7 and y < 0, nlelt, lstelt)
do ilelt = 1, nlelt
ifac = lstelt(ilelt)

xCentre = cdgfbo(1,ifac)
yCentre = cdgfbo(2,ifac)
alfa = atan(yCentre / xCentre)
beta = alfa + pi/2.0

do iphas = 1, nphas
itypfb(ifac,iphas) = iparoi
rcodcl(ifac,iu(iphas),1) = lowerActuatorValue * cos(beta)
rcodcl(ifac,iv(iphas),1) = lowerActuatorValue * sin(beta)
rcodcl(ifac,iw(iphas),1) = 0.0d0
enddo
enddo

return
end subroutine

F.5. Identificador del Sistema en Matlab


F.5.1. lfd arx.m

function [A B] = lfd_arx(y, u, p)
y = y;
u = u;

na = p;
nb = na+1;
%Modelo de partida:
% y(k)+a_1*y(k-1)+a_2*y(k-2)+...a_na*y(k-na)=

Apendice F. Codigos Fuente 189


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

% =b_1*u(k)+b_2*u(k-1)+...+b_nb*u(k-(nb-1))
%donde
% y(k) es la salida en el tiempo k, vector de mx1
% u(k) es la entrada en el tiempo k, vector de rx1
% a_1,..a_na matrices de mxm
% b_1,...b_nb matrices de mxr
%venimos considerando na=nb-1
%De acuerdo con esta escritura, se considera
% N:cantidad de observaciones
% y: matriz de observaciones de las salidas, de mxN; es decir, en la
%columna j la salida en el tiempo j
% u: matriz de las observaciones de las entradas, de rxN; es decir, en la columna j la entrada en el
tiempo j

%segon Ljung, se define el vector de regresion en el tiempo k como:


% fi(k)=(-y(k-1), ...,-y(k-na),u(k), u(k-1),...u(k-(nb-1))
% y el "vector" de parometros a calcular mp=(a_1,...,a_na,_1,...b_nb)

[m,N] = size(y);
[r,N] = size(u);

%se construye fi con los valores de regresion, considerando los tiempos de


%na+1 en adelante
fi = zeros(na*m+nb*r,N);
for j=na+1:N
fi(:,j)=[reshape(-y(:, j-1:-1:j-na), na*m, 1); ...
reshape(u(:, j:-1:j-(nb-1)), nb*r, 1)];
end

%se construye la matriz de regresion


fi2 = fi(:, na+1:end);
reg = zeros(m*size(fi2,1), m*(N-na));
for j=1:N-na
reg(:, 1+(j-1)*m:j*m) = kron(fi2(:,j), eye(m));
end

%REVISAR SIG LINEA


yna = y(:, na+1:end);
Y = reshape(yna, m*(N-na), 1);

F = [reg Y];
R = triu(qr(F));

%d: cantidad de nomeros a determinar para armar las matrices %del modelo
d = na*m*m+nb*r*m;
R0 = R(1:d+1,1:d+1);
R1 = R0(1:d,1:d);
R2 = R0(1:d,end);

%se desecha la parte Q de la matriz F y se resuelve por cuad. monimos


%th: resultante que contiene los valores para armar las matrices A y B
th = pinv(R1) * R2;

a = zeros(m, m, na);
b = zeros(m, r, nb);
for j=1:na
a(:,:,j)=reshape(th(1+(j-1)*m*m:j*m*m),m,m);
end
for j=1:nb
b(:,:,j)=reshape(th(1+na*m*m+(j-1)*m*r:1+na*m*m+(j-1)*m*r+m*r-1),m,r);
end

A = zeros(m, m, na+1);
A(:,:,1) = eye(m);
A(:,:,2:end) = a(:,:,:);
B = b;

Apendice F. Codigos Fuente 190


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.5.2. lfd compare.m

function [ fit ] = lfd_compare(data, max_steps_to_predict, model)


%LFD_COMPARE Compares a given system identification model against the real data
% Returns the Fit information.

y = pvget(data, OutputData);
y = y{1};
ny = size(y , 2);

y_predicted = predict(model, data, max_steps_to_predict, e);


y_predicted = pvget(y_predicted, OutputData);
y_predicted = y_predicted{1};

fit = zeros(ny, 1);


for ky = 1:ny
err = norm(y_predicted(:, ky) - y(:, ky));
meanerr = norm(y(:, ky) - mean(y(:, ky)));
fit(ky) = 100*(1-err/meanerr);
end

% Original code adapted from the compare function in the System


% Identification toolbox:
% ksys = 1;
% th = model;
% z1 = data;
% m = Inf;
% kexp = 1;
%
% y = pvget(data, OutputData);
% y{1} = y{ksys,kexp};
% [nrow, ny] = size(y{1});
% [nrow, nu] = size(u);
%
% sampizf{1} = 1:nrow;
% ksysinit = e;
%
% [yh{ksys}, x01{ksys}] = predict(th, z1, m, ksysinit);
% yhh = pvget(yh{ksys}, OutputData);
%
% for ky = 1:ny
% kyy = ky;
% err = norm(yhh{kexp}(sampizf{kexp}, kyy) - y{kexp}(sampizf{kexp}, ky));
% meanerr = norm(y{kexp}(sampizf{kexp}, ky) - mean(y{kexp}(sampizf{kexp}, ky)));
% fit(kexp, ksys, ky) = 100*(1-err/meanerr);
% end
end

F.5.3. lfd training actuation.m

function act = lfd_training_actuation(totalSteps, freq_range, amplitude)


% Computes the actuation for a training phase for a given amount of totalSteps. It is possible to
% define amount of random phases of actuation and frequency, modulus, etc. per each.
% Params: totalSteps, amountOfPhases, allowable_freq_range, allowable_modulus_range, stepDifference

s = RandStream.create(mrg32k3a,NumStreams,1);
RandStream.setDefaultStream(s); %to ensure deterministic output
%randseed(45233); %to ensure deterministic output

act = chirp(1:totalSteps, freq_range(1), totalSteps, freq_range(2))*amplitude;


act = repmat(act, 1, 2);
end

Apendice F. Codigos Fuente 191


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.5.4. lfd training actuation gaussian.m

function act = lfd_training_actuation_gaussian(peakMagnitude, totalSteps, meanStep, sigma)


% Computes the actuation for a training phase for a given amount of totalSteps. It is possible to
% Params: totalSteps, amountOfPhases, allowable_freq_range, allowable_modulus_range, stepDifference
steps = 1:totalSteps;
act = peakMagnitude * exp(-((steps-meanStep).^2)/(2*sigma^2));
act = repmat(act, 1, 2);
end

F.5.5. lfd training actuation multiple gaussian.m

function act = lfd_training_actuation_multiple_gaussian(peakMagnitude, totalSteps, meanSteps, sigma)


% Computes the actuation for a training phase for a given amount of totalSteps. It is possible to
% Params: totalSteps, amountOfPhases, allowable_freq_range, allowable_modulus_range, stepDifference
steps = 1:totalSteps;
act = zeros(1, totalSteps);
for ii=1:length(meanSteps)
meanStep = meanSteps(ii);
gaussian = peakMagnitude * exp(-((steps-meanStep).^2)/(2*sigma^2));
act = act + gaussian;
end

act = repmat(act, 1, 2);


end

F.5.6. lfd training actuation pulse.m

function act = lfd_training_actuation_pulse(pulseMagnitude, delayBeforePulseSteps, pulseSteps,


delayAfterPulseSteps)
% Computes the actuation for a training phase for a given amount of totalSteps. It is possible to
% define amount of random phases of actuation and frequency, modulus, etc. per each.
% Params: totalSteps, amountOfPhases, allowable_freq_range, allowable_modulus_range, stepDifference

s = RandStream.create(mrg32k3a,NumStreams,1);
RandStream.setDefaultStream(s); %to ensure deterministic output
%randseed(45233); %to ensure deterministic output

totalSteps = delayBeforePulseSteps + pulseSteps + delayAfterPulseSteps;


act = zeros(1, totalSteps);
act(delayBeforePulseSteps+1:delayBeforePulseSteps+pulseSteps) = pulseMagnitude;
act = repmat(act, 1, 2);
end

F.5.7. lfd training actuation ramp.m

function act = lfd_training_actuation_ramp(peakMagnitude, delayBeforeRampSteps, rampUpSteps, rampDownSteps,


delayAfterRampSteps)
% Computes the actuation for a training phase for a given amount of totalSteps. It is possible to
% Params: totalSteps, amountOfPhases, allowable_freq_range, allowable_modulus_range, stepDifference

totalSteps = delayBeforeRampSteps + rampUpSteps + rampDownSteps + delayAfterRampSteps;


act = zeros(1, totalSteps);
deltaRampUp = 1/rampUpSteps;
deltaRampDown = 1/rampDownSteps;
act(delayBeforeRampSteps+1:delayBeforeRampSteps+rampUpSteps) = peakMagnitude*[deltaRampUp:
deltaRampUp:1];

Apendice F. Codigos Fuente 192


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

act(delayBeforeRampSteps+rampUpSteps+1:delayBeforeRampSteps+rampUpSteps+rampDownSteps) =
peakMagnitude*[1-deltaRampDown:-deltaRampDown:0];
act = repmat(act, 1, 2);
end

F.6. Controlador en C++


F.6.1. main.cpp

/*
In order to compile the code it is possible to run the "mex" command either via Matlab or Linux Shell:
Matlab: mex(-v, -f, fullfile(matlabroot,bin,engopts.sh),controlador.cpp, Parser.cpp,
MatlabExecutor.cpp, etc)
Shell: mex -v -f /usr/local/opt/matlab2009/bin/engopts.sh main.cpp Parser.cpp MatlabExecutor.cpp
Controller.cpp SaturneCommunicator.cpp -o controller

Run with:
LD_LIBRARY_PATH=/usr/local/opt/matlab2009/bin/glnxa64:/usr/local/opt/matlab2009/sys/os/glnxa64:
$LD_LIBRARY_PATH
sudo ldconfig /usr/local/opt/matlab2009/bin/glnxa64
./controller
*/

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <limits>
#include <algorithm>
#include "Parser.h"
#include "Logger.h"
#include "MatlabExecutor.h"
#include "Controller.h"
#include "SaturneCommunicator.h"
#include "Constants.h"

int main(int argc, char* argv[]) {


if (argc != 5) {
std::cerr << "Se esperaban 4 argumentos. Modo de uso: ./controlador <processor-number> <upper-actuator-
output-file> <lower-actuator-output-file> <probes-pressure-input-file> < semaforo." << std::endl;
return 1;
}
else {
std::string logFilepath;
std::string logPrefix;
std::stringstream converter;
converter << "controlador.log." << argv[1];
converter >> logFilepath;

std::stringstream prefixConverter;
prefixConverter << "[CPU." << argv[1] << "]";
prefixConverter >> logPrefix;

Logger logger(logPrefix, logFilepath);


Parser parser(logger, PROBES_COUNT);
MatlabExecutor matlabExecutor(logger);
logger << "Abriendo archivo actuador alto: " << argv[2] << "." << std::endl;
std::ofstream upperActuator(argv[2]);
logger << "Abriendo archivo actuador bajo: " << argv[3] << "." << std::endl;
std::ofstream lowerActuator(argv[3]);
char* probesPressureFilepath = argv[4];

Apendice F. Codigos Fuente 193


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

logger << "Tomando semaforo de STDIN..."<< std::endl;


std::istream& semaphore = std::cin;

try {
Controller controller(argv[1], logger, matlabExecutor);
SaturneCommunicator saturneCommunicator;

controller.initialize("configuration.txt");
bool continueControl = true;
while (continueControl) {
int semaphoreStepNumber = saturneCommunicator.waitForStep(semaphore, logger);
if (semaphoreStepNumber >= 0) {
Row values = parser.readValues(probesPressureFilepath , semaphoreStepNumber - 1);
Actuation act = controller.getActuationFor(semaphoreStepNumber, values);

saturneCommunicator.send(upperActuator, logger, act.upper);


saturneCommunicator.send(lowerActuator, logger, act.lower);
}
else {
logger << "Seoal de cierre recibida. Finalizando..." << std::endl;
continueControl = false;
}
}
return 0;
}
catch(const char* message) {
logger << "ERROR DURING SIMULATION: " << message << std::endl;
return 1;
}
catch(...) {
logger << "UNKNOWN ERROR DURING SIMULATION: " << std::endl;
return 1;
}
}
}

F.6.2. Config.h

#ifndef CONFIG__
#define CONFIG__

#include <map>
#include <string>
#include <fstream>

class Config {
private:
typedef std::map< std::string, std::string > t_keyvalues;
typedef std::pair< std::string, std::string > t_keyvalue;
t_keyvalues keyValues;
public:
Config(const std::string& configurationFilepath){
initialize(configurationFilepath);
}
Config(){
}

void initialize(const std::string& configurationFilepath) {


std::ifstream keyValuesFile(configurationFilepath.c_str());
if (! keyValuesFile)
throw "There was an error trying to read the configuration file.";
else {
while(keyValuesFile.good()) {
std::string line;
getline(keyValuesFile, line);
trim(line);

Apendice F. Codigos Fuente 194


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

if (!line.empty()){
std::string::size_type pos = line.find_first_of("=");
if (pos != std::string::npos) {
std::string key = line.substr(0, pos-1);
std::string value = line.substr(pos+1, line.size());
trim(key);
trim(value);
keyValues.insert(t_keyvalue(key, value));
}
}
}

}
}

float getFloat(const std::string& key) {


return get< float >(key);
}

bool getBool(const std::string& key) {


return get< bool >(key);
}

int getInt(const std::string& key) {


return get< int >(key);
}

std::string get(const std::string& key) {


t_keyvalues::iterator it = keyValues.find(key);
if (it == keyValues.end()) {
std::stringstream ss;
ss << "The key " << key << "was not found.";
throw ss.str().c_str();
}
else
return it->second;
}

private:
void trim(std::string& str, const std::string trimChars = std::string(" \f\n\r\t\v") ) {
std::string::size_type pos;
pos = str.find_last_not_of(trimChars);
str.erase( pos + 1 );
pos = str.find_first_not_of(trimChars);
str.erase( 0, pos );
}

template < typename T >


T get(const std::string& key) {
std::string value = get(key);
std::stringstream ss;
ss << value;
T result;
ss >> result;
return result;
}
};

#endif

F.6.3. configuration control.txt

CONTROL_PARAMETER_P = 90
CONTROL_PARAMETER_Q = [1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4]
CONTROL_PARAMETER_GAMMA = 4
CONTROL_LIMITS_MAX_VALUE = 5
CONTROL_LIMITS_MIN_VALUE = 0

Apendice F. Codigos Fuente 195


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

CONTROL_CALCULATE_ACTUATION_AFTER_STEPS = 1
CONTROL_PREDICTION_MAX_STEPS = 1000

SENSORS_MASK_PROBES_TO_USE = 7,9,11,13,48,50,52,54
SENSORS_NORMALIZE_VARIABLE_Y_SENTENCE = if ~exist(yNormalizerScalars),global yNormalizerScalars;range =
1:170; yNormalizerScalars=diag(1./mean(y(range,:)));end;y=y*yNormalizerScalars;
ACTUATOR_UPPERVALUE_ARRAYINDEX = 0
ACTUATOR_LOWERVALUE_ARRAYINDEX = 0
ACTUATOR_NORMALIZE_VARIABLE_U_SENTENCE = u=u(:,1);

SAVE_OUTPUT_FILEPATH = outputs.csv
SAVE_INPUT_FILEPATH = inputs.csv

TRAINING_FROM_STORED_DATA_ENABLED = 1
TRAINING_FROM_STORED_DATA_FILEPATH = ProbesAndActuation_one_pulse_sync_r235_full_line.mat
TRAINING_FROM_STORED_DATA_OUTPUT_VARIABLE = scalar_values
TRAINING_FROM_STORED_DATA_INPUT_VARIABLE = actuation
TRAINING_FROM_STORED_DATA_SAMPLING_RATE = 1

TRAINING_GENERATION_ENABLED = 0
TRAINING_GENERATION_FUNCTION_INVOKE = %lfd_training_actuation_pulse(10, 375, 37, 3750)
COMPUTE_MODEL_STEPS = 1

F.6.4. configuration training.txt

CONTROL_PARAMETER_P = 35
CONTROL_PARAMETER_Q = [1 1 1 1]
CONTROL_PARAMETER_GAMMA = 0.8
CONTROL_LIMITS_MAX_VALUE = 3
CONTROL_LIMITS_MIN_VALUE = 0
CONTROL_CALCULATE_ACTUATION_AFTER_STEPS = 1
CONTROL_PREDICTION_MAX_STEPS = 1000

SENSORS_MASK_PROBES_TO_USE = 4,6,13,15
SENSORS_NORMALIZE_VARIABLE_Y_SENTENCE = if ~exist(yNormalizerScalars),global yNormalizerScalars;
yNormalizerScalars=diag(1./mean(y));end;y=y*yNormalizerScalars;
ACTUATOR_UPPERVALUE_ARRAYINDEX = 0
ACTUATOR_LOWERVALUE_ARRAYINDEX = 0
ACTUATOR_NORMALIZE_VARIABLE_U_SENTENCE = u=u(:,1);

SAVE_OUTPUT_FILEPATH = outputs.csv
SAVE_INPUT_FILEPATH = inputs.csv

TRAINING_FROM_STORED_DATA_ENABLED = 0
TRAINING_FROM_STORED_DATA_FILEPATH = %ProbesAndActuation_mixed_sync.mat
TRAINING_FROM_STORED_DATA_OUTPUT_VARIABLE = %scalar_values
TRAINING_FROM_STORED_DATA_INPUT_VARIABLE = %actuation
TRAINING_FROM_STORED_DATA_SAMPLING_RATE = %10

TRAINING_GENERATION_ENABLED = 1
TRAINING_GENERATION_FUNCTION_INVOKE = lfd_training_actuation_pulse(10, 180, 10, 900)
COMPUTE_MODEL_STEPS = 10

F.6.5. Constants.h

#ifndef CONSTANTS__
#define CONSTANTS__

#define LINE_PROBES 11.0 //nLineProbes = 11 check values in usini1.f90


#define SAMPLES_PER_LINE 9.0 //nSamplesPerLine = 9 check values in usini1.f90
#define PROBES_COUNT LINE_PROBES*SAMPLES_PER_LINE
#define X_STEP 1.0 //1 diametre in between line probes

Apendice F. Codigos Fuente 196


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

#define Y_STEP (6.0+6.0)/SAMPLES_PER_LINE //based on the amount of samples per line. Having 12.5 diametres
to the upper and bottom limits of the tunnel.

#include <vector>
#include "Matrix.h"

struct Actuation {
Cell upper;
Cell lower;
};

#endif

F.6.6. Controller.h

#ifndef CONTROLLER__
#define CONTROLLER__

#include <vector>
#include <set>
#include "Logger.h"
#include "MatlabExecutor.h"
#include "Constants.h"
#include "Config.h"

class Controller {
private:
Matrix cummulativeOutputsForModel, cummulativeOutputs;
Matrix cummulativeActuationForModel, cummulativeActuation;
std::vector < Actuation > trainingActuations;
std::vector < Actuation >::const_iterator itTrainingActuation;
Actuation previousActuation;

bool initialized;
bool modelAlreadyComputed;
size_t invocationsCount;
char* processorNumber;
std::set< size_t > probesToUse;
Logger& logger;
MatlabExecutor& matlabExecutor;
std::ofstream inputsLogFile;
std::ofstream outputsLogFile;
Config config;

public:
Controller(char* processorNumber, Logger& logger, MatlabExecutor& matlabExecutor);
void initialize(const std::string& configurationFilepath);
Actuation getActuationFor(int currentStep, const Row& lastStepOutputs);

private:
void addOutputsForModelComputation(const Row& lastStepOutputs, const Row& actuation);
std::vector < Actuation > getTrainingActuation();
Actuation getActuationFromRow(const Row& row);
void computeModel();
Actuation computeActuation();
Actuation getActuationForNewStep();

Matrix removeUselessProbeValues(const Matrix& values);


Row removeUselessProbeValues(const Row& values);
void checkInitialized();
void restoreTrainingData();
void saveLastStepInformation(int currentStep, const Actuation& input, const Row& output);
};

#endif

Apendice F. Codigos Fuente 197


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.6.7. Controller.cpp

#include <sstream>
#include <set>
#include "Controller.h"

Controller::Controller(char* processorNumber, Logger& logger, MatlabExecutor& matlabExecutor)


: cummulativeOutputsForModel(0,0), cummulativeOutputs(0,0), cummulativeActuationForModel(0,0),
cummulativeActuation(0,0),
initialized(false), modelAlreadyComputed(false), invocationsCount(0), processorNumber(
processorNumber), logger(logger), matlabExecutor(matlabExecutor) {

void Controller::initialize(const std::string& configurationFilepath) {


this->config.initialize(configurationFilepath);
this->previousActuation.upper = 0;
this->previousActuation.lower = 0;
this->initialized = true;

inputsLogFile.open(config.get("SAVE_INPUT_FILEPATH").c_str(), std::ofstream::out);
outputsLogFile.open(config.get("SAVE_OUTPUT_FILEPATH").c_str(), std::ofstream::out);
if (! inputsLogFile.good())
throw "There was an error trying to open the input file";
if (! outputsLogFile.good())
throw "There was an error trying to open the output file";

std::istringstream maskProbesToUseStr(config.get("SENSORS_MASK_PROBES_TO_USE"));
logger << "Defining Mask Probes to use: ";
std::string probeToUse;
while ( getline(maskProbesToUseStr, probeToUse, ,) )
{
this->probesToUse.insert(atoi(probeToUse.c_str()));
logger << " " << probeToUse;
}
logger << std::endl;

bool trainingFromStoredData = config.getBool("TRAINING_FROM_STORED_DATA_ENABLED");


bool trainingGeneration = config.getBool("TRAINING_GENERATION_ENABLED");
if (trainingFromStoredData && trainingGeneration || !trainingFromStoredData && !trainingGeneration)
throw "It is neccessary to define whether TRAINING_FROM_STORED_DATA or TRAINING_GENERATION will be used
in the configuration file.";
if (trainingFromStoredData) {
//let trainining to be empty
this->itTrainingActuation = this->trainingActuations.begin();
this->restoreTrainingData();
logger << "Before computing model. CummulativeOutputs Rows: " << cummulativeOutputsForModel.getRows()
<< " - Cols: " << cummulativeOutputsForModel.getColumns() << std::endl;
this->computeModel();
}
else { //trainingGeneration
//Create a training function and use it during the first steps
this->trainingActuations = this->getTrainingActuation();
this->itTrainingActuation = this->trainingActuations.begin();
}
}

void Controller::restoreTrainingData() {
std::ostringstream loadExpression;
loadExpression << "load("<< config.get("TRAINING_FROM_STORED_DATA_FILEPATH") << ");";
loadExpression << "y = " << config.get("TRAINING_FROM_STORED_DATA_OUTPUT_VARIABLE") << ";";
loadExpression << "u = " << config.get("TRAINING_FROM_STORED_DATA_INPUT_VARIABLE") << ";";
loadExpression << "y = y(1:" << config.getInt("TRAINING_FROM_STORED_DATA_SAMPLING_RATE") << ":end,:);";
loadExpression << "u = u(1:" << config.getInt("TRAINING_FROM_STORED_DATA_SAMPLING_RATE") << ":end,:);";
matlabExecutor.evaluate(loadExpression.str());

Matrix yMatrix = matlabExecutor.getMatrix("y");

Apendice F. Codigos Fuente 198


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

logger << "Received y data values. Rows: " << yMatrix.getRows() << ". Cols: " << yMatrix.getColumns() <<
std::endl;

cummulativeOutputs = yMatrix;
cummulativeOutputsForModel = yMatrix;

Matrix uMatrix = matlabExecutor.getMatrix("u");


logger << "Received u data values. Rows: " << uMatrix.getRows() << ". Cols: " << uMatrix.getColumns()
<< std::endl;

if (uMatrix.getRows() != yMatrix.getRows()) {
logger << "Error computing restarting values. u amount of samples should match y amount of samples.
ySamples:" << yMatrix.getRows() << " uySamples:" << uMatrix.getRows() << std::endl;
throw "Error computing training actuation values.";
}
else {
cummulativeActuation = uMatrix;
cummulativeActuationForModel = uMatrix;
}
matlabExecutor.evaluate("clear y u;");
cummulativeOutputs = this->removeUselessProbeValues(cummulativeOutputs);
cummulativeOutputsForModel = this->removeUselessProbeValues(cummulativeOutputsForModel);
}

void Controller::checkInitialized() {
if (! this->initialized)
throw "The controller was not initialized yet.";
}

Actuation Controller::getActuationForNewStep() {
this->checkInitialized();
if (itTrainingActuation != trainingActuations.end()) {
Actuation act = *itTrainingActuation;
++itTrainingActuation;
logger << "Taking training actuation: [" << act.lower << ", " << act.upper << "]" << std::endl;
return act;
}
else {
logger << "Computing actuation from sensor values ..." << std::endl;
return this->computeActuation();
}
}

std::vector < Actuation > Controller::getTrainingActuation() {


std::stringstream expression;
expression << "training_act = " << config.get("TRAINING_GENERATION_FUNCTION_INVOKE") << ";";
matlabExecutor.evaluate(expression.str());
Matrix trainingAct = matlabExecutor.getMatrix("training_act");
matlabExecutor.evaluate("clear training_act;");
logger << "Received training actuation with " << trainingAct.getRows() << " samples." << std::endl;
if (trainingAct.getColumns() != 2 ) {
logger << "Error computing training actuation values. Expected actuation values per sample: 2 " << std
::endl;
throw "Error computing training actuation values.";
}

std::vector < Actuation > result;


for(size_t i = 0; i < trainingAct.getRows(); ++i) {
result.push_back(this->getActuationFromRow(trainingAct[i]));
}
return result;
}

void Controller::computeModel() {
std::ostringstream expression;
expression << "p = " << config.getInt("CONTROL_PARAMETER_P") << "; gamma= " << config.getFloat("
CONTROL_PARAMETER_GAMMA") << ";";
expression << "q = " << config.get("CONTROL_PARAMETER_Q") << ";";
matlabExecutor.evaluate(expression.str());

Apendice F. Codigos Fuente 199


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

expression.str(" ");
expression << "limits.max_value = " << config.getInt("CONTROL_LIMITS_MAX_VALUE") << "; limits.min_value =
" << config.getInt("CONTROL_LIMITS_MIN_VALUE") << ";";
matlabExecutor.evaluate(expression.str());
matlabExecutor.putMatrix("y", cummulativeOutputsForModel);
matlabExecutor.putMatrix("u", cummulativeActuationForModel);
std::ostringstream saveExpression;
saveExpression << "save model_data."<< processorNumber <<".dat y u;";
matlabExecutor.evaluate(saveExpression.str());
matlabExecutor.evaluate(config.get("SENSORS_NORMALIZE_VARIABLE_Y_SENTENCE"));
matlabExecutor.evaluate(config.get("ACTUATOR_NORMALIZE_VARIABLE_U_SENTENCE"));
matlabExecutor.evaluate("data = iddata(y, u);");
matlabExecutor.evaluate("[A B] = lfd_arx(data.OutputData, data.InputData, p);");
matlabExecutor.evaluate("control_state = lfd_control_lagrange_init(y, u, p, gamma, A, B, limits, q);");
matlabExecutor.evaluate("clear data y u A B limits;");
}

Actuation Controller::computeActuation() {
matlabExecutor.putMatrix("y", cummulativeOutputs);
matlabExecutor.putMatrix("u", cummulativeActuation);
matlabExecutor.evaluate(config.get("SENSORS_NORMALIZE_VARIABLE_Y_SENTENCE"));
matlabExecutor.evaluate(config.get("ACTUATOR_NORMALIZE_VARIABLE_U_SENTENCE"));
matlabExecutor.evaluate("control_state = lfd_control_lagrange(control_state, y, u);");
matlabExecutor.evaluate("next_step_act = control_state.u_k;");
matlabExecutor.evaluate("clear y u;");

Matrix result = matlabExecutor.getMatrix("next_step_act");


if (result.getRows() != 1) {
logger << "Error computing next actuation value. One actuation was expected. Received actuations: "
<< result.getRows() << std::endl;
throw "Error computing next actuation value. One actuation was expected.";
}
else
return this->getActuationFromRow(result[0]);
}

Actuation Controller::getActuationFromRow(const Row& row) {


unsigned int upperActIndex = config.getInt("ACTUATOR_UPPERVALUE_ARRAYINDEX");
unsigned int lowerActIndex = config.getInt("ACTUATOR_LOWERVALUE_ARRAYINDEX");
unsigned int actIndexMax = (lowerActIndex > upperActIndex) ? lowerActIndex: upperActIndex;
if (row.getColumns() < actIndexMax) {
logger << "Error computing actuation values. Received values do not match the configuration indices for
upper and lower actuator. Available indices: " << row.getColumns() << "Upper index:" <<
upperActIndex << ". Lower index:" << lowerActIndex << std::endl;
throw "Error computing next actuation values. Configuration index mismatch";
}
else {
Actuation act;
act.upper = row[upperActIndex];
act.lower = row[lowerActIndex];
return act;
}
}

void Controller::addOutputsForModelComputation(const Row& lastStepOutputs, const Row& actuation) {


if (! modelAlreadyComputed) {
if (cummulativeActuationForModel.getRows() < config.getInt("COMPUTE_MODEL_STEPS")) {
cummulativeActuationForModel.pushRow(actuation);
cummulativeOutputsForModel.pushRow(lastStepOutputs);
}
if (cummulativeActuationForModel.getRows() == config.getInt("COMPUTE_MODEL_STEPS")) {
this->computeModel();
this->modelAlreadyComputed = true;
}
}
}

Matrix Controller::removeUselessProbeValues(const Matrix& values) {


Matrix normalizedMatrix(0, 0);
for(size_t i = 0; i < values.getRows(); ++i) {

Apendice F. Codigos Fuente 200


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Row normalizedRow = this->removeUselessProbeValues(values[i]);


normalizedMatrix.pushRow(normalizedRow);
}
if (values.getRows() > 0) {
logger << "Normalization finished. Input amount of samples for first line. Original:" << values[0].
getColumns() << " normalized:" << normalizedMatrix[0].getColumns() << std::endl;
}
return normalizedMatrix;
}

Row Controller::removeUselessProbeValues(const Row& values) {


Row normalizedRow(0);
for(size_t i = 0; i < values.getColumns(); ++i) {
if (probesToUse.end() != probesToUse.find(i + 1)) {
normalizedRow.pushCell(values[i]);
}
}
return normalizedRow;
}

void Controller::saveLastStepInformation(int currentStep, const Actuation& input, const Row& output) {


this->inputsLogFile << currentStep << , << input.upper << , << input.lower << std::endl;
this->outputsLogFile << currentStep;
for(size_t i = 0; i < output.getColumns(); ++i) {
this->outputsLogFile << , << output[i];
}
this->outputsLogFile << std::endl;
}

Actuation Controller::getActuationFor(int currentStep, const Row& lastStepOutputs) {


Row lastStepOutputsNormalized = this->removeUselessProbeValues(lastStepOutputs);

Actuation act;
if ((invocationsCount % config.getInt("CONTROL_CALCULATE_ACTUATION_AFTER_STEPS")) != 0) {
act = this->previousActuation;
}
else {
logger << "Calculating actuation for step: " << currentStep << std::endl;
act = this->getActuationForNewStep();

Row actRow(2);
actRow[0] = act.upper;
actRow[1] = act.lower;

cummulativeActuation.pushRow(actRow);
cummulativeOutputs.pushRow(lastStepOutputsNormalized);

this->addOutputsForModelComputation(lastStepOutputsNormalized, actRow);

if (cummulativeOutputs.getRows() > config.getInt("CONTROL_PREDICTION_MAX_STEPS")) {


size_t indexFrom = cummulativeOutputs.getRows() - config.getInt("CONTROL_PREDICTION_MAX_STEPS");
cummulativeOutputs = cummulativeOutputs.submatrixByRows(indexFrom, cummulativeOutputs.getRows() -1);
cummulativeActuation = cummulativeActuation.submatrixByRows(indexFrom, cummulativeActuation.getRows()
-1);
}
logger << "Finished: Calculating actuation for step: " << currentStep << std::endl;
}
++this->invocationsCount;
this->previousActuation = act;
this->saveLastStepInformation(currentStep, act, lastStepOutputs);
return act;
}

F.6.8. Logger.h

#ifndef LOGGER__

Apendice F. Codigos Fuente 201


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

#define LOGGER__

#include <iostream>
#include <fstream>

class Logger {
private:
bool includePrefix;
std::string prefix;
std::ofstream file;
public:
typedef std::ostream& (*ostream_manipulator)(std::ostream&);
Logger(const std::string& prefix, const std::string& filepath) : includePrefix(true), prefix(prefix),
file(filepath.c_str()) {
if (!file)
std::cerr << "Error al inicializar el log en " << filepath << "." << std::endl;
}

template< typename T >


Logger& operator<<(const T& msg){
if (includePrefix) {
this->file << this->prefix;
std::cout << this->prefix;
includePrefix = false;
}
this->file << msg;
this->file.flush();
std::cout << msg;
std::cout.flush();
return *this;
}
Logger& operator<<(ostream_manipulator pf)
{
this->includePrefix = true;
pf(this->file);
pf(std::cout);
return *this;
}

};

#endif

F.6.9. lfd control lagrange init.m

function [ control_state ] = lfd_control_lagrange_init(y, u, p, gamma, A, B, limits, q)


%Parameters:
% y: m*N matrix with the output values
% u: r*N matrix with inputs
% p: orden del modelo ARX
% A: m*m*(p+1). ARX coefficient matrix
% B: m*r*(p+1). ARX coefficient matrix
% q: m*s weights vector. Should have values between 0 and 1. Q=diag(q) will
% gamma: actuation cost
% be used for the control iteration
% where N: observations count
%
% Usage example:
% [A, B] = lfd_arx(y, u, 2);
% limits.min_value = 0;
% limits.max_value = 3;
% control_state = lfd_control_lagrange_init(y, u, 2, 0.99999, 1/625000, A, B, limits, ones(1,sizeof(y,2)))
;
% next_actuation = lfd_control_lagrange(control_state, y, u);

Apendice F. Codigos Fuente 202


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

%In order to get a proper control algorithm, the functional was defined as
% min(y_s^tQy_s+gamma u_s^u_s)
%Where y_s=(y_k y_k+1 ...y_k+s-1)
% u_s=(u_k u_k+1 ...u_k+s-1)
%Then, it can be applied as:
% u_s = K * v_p
%Where v_p = (y_k-1..y_k-p u_k-1...u_k-p)
% y_s = T*u_s + phi*v_p ,
%Then, the K matrix can be computed as
% K = -inv(TQ*T+gamma*I)*T*Q*phi

y = y;
u = u;

if size(y,2) ~= size(u,2)
error(lfd_control:input,Unable to determine current time step number: k. Samples in y(count: %d) and
u(count: %d) do not match, size(y,2), size(u,2));
end

%m: y components count


%r: u components count
m = size(y,1);
r = size(u,1);

%s: prediction horizont (should be between 2 and 3 times p)


s=3*p;

% k should match the following rule to allow vp collection: k-p >=1,


k = size(y,2);
if k-p < 1
error(lfd_control:k_validation, Arguments error. TimeStep and Order should match the following rule:
k-p>=1. k: %d,p: %d, k, p);
end

%Since Matlab ARX convention includes y coefficients on the right


%side, starting with the identity matrix, we should re-arrange the info
a = -A(:,:,2:end);
b = B;

% Being y(k) = a_1*y(k-1)+a_2*y(k-2)+...a_p*y(k-p) +


% b_0*u(k)+b_1*u(k-1)+...+b_p*u(k-p)
% The markov parameters can be defined as:
% alpha_1^0 = a_1,..., alpha_1^k = a_1 if k = 0
% ..., alpha_1^k = a_k+1 + sum_1^k(a_i*alpha_1^k-i) if k = 1, 2, .. p-1
% ..., alpha_1^k = sum_1^p(a_i*alpha_1^k-i) if k = p, p+1, ...
% beta_0^0 = b_0,..., beta_0^k = b_0 if k = 0
% ..., beta_0^k = b_k + sum_1^k(a_i*beta_0^k-i) if k = 1, 2, .. p
% ..., beta_0^k = sum_1^p(a_i*beta_0^k-i) if k = p+1,
% p+2, ..
beta00 = b(:,:,1);
beta0 = zeros(m, r, s-1);
beta0(:,:,1) = b(:,:,2) + a(:,:,1)*beta00;

for kk=2:s-1
if kk<=p
aux=zeros(size(beta00));
for l=1:kk-1;
aux=aux+a(:,:,l)*beta0(:,:,kk-l);
end
aux=aux+a(:,:,kk)*beta00;
beta0(:,:,kk) = b(:,:,kk+1)+aux;
else
aux=zeros(size(beta00));
for l=1:p;

Apendice F. Codigos Fuente 203


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

aux=aux+a(:,:,l)*beta0(:,:,kk-l);
end
beta0(:,:,kk)=aux;
end
end
clear aux

% T: [beta_0^0 0 0 ... 0;
% beta_0^1 beta_0^0 0 ... 0;
% beta_0^2 beta_0^1 beta_0^0 0 ... 0;
% ...
% beta_0^s-1 ... beta_0^1 beta_0^0]

%T y phi se definen a partir de los parometros de markov que se encuentran en A y B


T=zeros(m*s,r*s);
T_column =zeros(m*s,r);

T_column(1:m,:)=beta00;
for j=2:s;
T_column((j-1)*m+1:j*m,:)=beta0(:,:,j-1);
end;

for column = 1:s


T(m*(column-1)+1:m*s, r*(column-1)+1:r*column) = T_column(1:(m*s - (column-1)*m),:);
end;

% phi: [alpha_1^0 ... alpha_p^0 beta_1^0 ... beta_p^0 ;


% ... ;
% alpha_1^s-1 ... alpha_p^s-1 beta_1^s-1 ... beta_p^s-1]
%
% alpha_k^j = alpha_1^j-1 * a_k + alpha_k+1^j-1 if k= 1, 2, .., p-1
% alpha_1^j-1 * a_k if k= p
% beta_k^j = alpha_1^j-1 * b_k + beta_k+1^j-1 if k= 1, 2, .., p-1
% alpha_1^j-1 * b_k if k= p
phi=zeros(m*s,p*(m+r));

% The variables bellow adopt the following syntax:


% a(:,:,subIndex) -> a_subIndex == alpha_subIndex^0
% b(:,:,subIndex+1) -> b_subIndex == beta_subIndex^0
% alpha(:,:,superIndex,subIndex) -> alpha_subIndex^superIndex
% beta(:,:,superIndex,subIndex) -> beta_subIndex^superIndex
for kk=1:p-1;
alpha(:,:,1,kk)=a(:,:,1)*a(:,:,kk)+a(:,:,kk+1);
end;
alpha(:,:,1,p)=a(:,:,1)*a(:,:,p);

for j=2:s-1;
for kk=1:p-1;
alpha(:,:,j,kk)=alpha(:,:,j-1,1)*a(:,:,kk)+alpha(:,:,j-1,kk+1);
end;
alpha(:,:,j,p)=alpha(:,:,j-1,1)*a(:,:,p);
end

for kk=1:p-1;
beta(:,:,1,kk)=a(:,:,1)*b(:,:,kk+1)+b(:,:,kk+2);
end
beta(:,:,1,p)=a(:,:,1)*b(:,:,p+1);

for j=2:s-1;
for kk=1:p-1;
beta(:,:,j,kk)=alpha(:,:,j-1,1)*b(:,:,kk+1)+beta(:,:,j-1,kk+1);
end;
beta(:,:,j,p)=alpha(:,:,j-1,1)*b(:,:,p+1);
end

Apendice F. Codigos Fuente 204


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

phi(1:m,:) = [reshape(a, m, m*p) reshape(b(:,:,2:end), m, r*p)];


for j=2:s
phi((j-1)*m+1:j*m,:) = [reshape(alpha(:,:,j-1,:), m, m*p) reshape(beta(:,:,j-1,:), m, r*p)];
end

% size(T*Q*T) = r*s;
gammaIdentitySize = r*s;

% Since: u_s = K*vp and only r rows are necessary from u_s, it is possible to reduce the computation
taking r rows from K
% Let K=-inv(gamma*eye(n)+T*Q*T)*T*Q*F, so r rows are necessary
% from -inv(gamma*eye(n)+T*Q*T) to compute the first r u_s components.
Q=kron(eye(s), diag(q));
invGammaTTQT = -pinv(gamma*eye(gammaIdentitySize) + T*Q*T);
control_state.K_r = invGammaTTQT(1:r, :) * T * Q * phi;
control_state.p = p;
control_state.limits = limits;
control_state.s = s;
control_state.m = m;
control_state.r = r;
control_state.gamma = gamma;
control_state.u_k = zeros(r, 1);
end

F.6.10. lfd control lagrange.m

function control_state = lfd_control_lagrange(control_state, y,u)

y = y;
u = u;

limits = control_state.limits;
p = control_state.p;
m = control_state.m;
r = control_state.r;
K_r = control_state.K_r;

k = size(y, 2) + 1;

vp = zeros(p*m+p*r, 1);
for i=1:p
vp((i-1)*m+1:i*m) = y(:,k-i);
end
offset = m*p;
for i=1:p
vp((i-1)*r+1+offset:i*r+offset) = u(:,k-i);
end;

%Finally: u_s = K*vp


%where u_s:control value from k to k+s-1
%So, lets take the first r values to compute only u_s(k)
u_k = K_r * vp;

indices_out_of_limit = find(u_k < limits.min_value);


u_k(indices_out_of_limit) = limits.min_value;
indices_out_of_limit = find(u_k > limits.max_value);
u_k(indices_out_of_limit) = limits.max_value;

control_state.u_k = u_k;
end

Apendice F. Codigos Fuente 205


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

F.6.11. MatlabExecutor.h

#ifndef MATLABEXECUTOR__
#define MATLABEXECUTOR__

#include <vector>
#include "engine.h"
#include "Logger.h"
#include "Matrix.h"

class MatlabExecutor {
private:
Engine *ep;
Logger& logger;
public:
MatlabExecutor(Logger& logger);
~MatlabExecutor();
void putMatrix(const std::string& matrixVariableName, Matrix& values);
Matrix getMatrix(const std::string& matrixVariableName);
void evaluate(const std::string& expression);
double evaluateScalar(const std::string& expression);
};

#endif

F.6.12. MatlabExecutor.cpp

#include <string.h>
#include "engine.h"
#include "MatlabExecutor.h"

MatlabExecutor::MatlabExecutor(Logger& logger) : logger(logger) {


logger << "Opening engine..." << std::endl;
if (!(ep = engOpen("\0"))) {
fprintf(stderr, "\nCant start MATLAB engine\n");
throw "Unable to start MATLAB engine";
}
}

MatlabExecutor::~MatlabExecutor() {
if (!(ep = engOpen("\0"))) {
logger << "Closing engine..." << std::endl;
engClose(ep);
}
}

void MatlabExecutor::putMatrix(const std::string& matrixVariableName, Matrix& values) {


if (values.getRows() == 0 || values.getColumns() == 0)
throw "Values are required";
mwSignedIndex rows = values.getRows();
mwSignedIndex cols = values.getColumns();
logger << "Calling Matlab for matrix " << rows << "x" << cols << std::endl;

mxArray *matrix = mxCreateDoubleMatrix(rows, cols, mxREAL);


double *ptrMatrix = mxGetPr(matrix);
logger << "Copying matrix..." << std::endl;
for(mwSignedIndex i = 0; i < rows; ++i) {
for(mwSignedIndex j = 0; j < cols; ++j) {
*(ptrMatrix + (j*rows) + i) = values.get(i,j);
}
}

logger << "Putting matrix. Variable: " << matrixVariableName << std::endl;
engPutVariable(ep, matrixVariableName.c_str(), matrix);
mxDestroyArray(matrix);

Apendice F. Codigos Fuente 206


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Matrix MatlabExecutor::getMatrix(const std::string& matrixVariableName) {


logger << "Getting matrix. Variable: " << matrixVariableName << std::endl;
mxArray *result;
if ((result = engGetVariable(ep,matrixVariableName.c_str())) == NULL) {
logger << "There was an error getting the values from variable " << matrixVariableName << "" << std::
endl;
throw "There was an error getting the values from a variable.";
}
else {
mwSize dimensionsCount = mxGetNumberOfDimensions(result);
if (dimensionsCount > 2) {
logger << "Matrices are prepared to be 2D only. The variable " << matrixVariableName << " was a ";
logger << dimensionsCount << "D." << std::endl;
throw "Matrices are prepared to be 2D only.";
}
else {
const mwSize* dimensions = mxGetDimensions(result);
mwSize rows = dimensions[0];
mwSize cols = dimensions[1];

Matrix matrix(rows, cols);


double* resultPtr = mxGetPr(result);
for(size_t i = 0; i < rows; ++i) {
for(size_t j = 0; j < cols; ++j) {
double value = *(resultPtr + (j*rows) + i);
matrix.set(i,j, value);
}
}
mxDestroyArray(result);
return matrix;
}
}
}

void MatlabExecutor::evaluate(const std::string& expression) {


#define BUFSIZE 1024
static char buffer[BUFSIZE+1];
memset(buffer, 0, sizeof(buffer));

engOutputBuffer(ep, buffer, sizeof(buffer) - 1);

logger << "Matlab. Evaluating: " << expression << std::endl;


engEvalString(ep, expression.c_str());
logger << "Matlab. Evaluation result: " << buffer << std::endl;
}

double MatlabExecutor::evaluateScalar(const std::string& expression) {


evaluate(expression);
mxArray *ans = NULL;
if ((ans = engGetVariable(ep,"ans")) == NULL) {
logger << "There was an error retrieving the answer of a previusly evaluated command." << std::endl;
throw "Error retrieving the answer of a previosly evaluated command.";
}
else {
double result = mxGetScalar(ans);
mxDestroyArray(ans);
return result;
}
}

F.6.13. Matrix.h

#ifndef MATRIX__

Apendice F. Codigos Fuente 207


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

#define MATRIX__

typedef double Cell;

class Row {
private:
std::vector< Cell > data;
public:
Row(size_t columns) {
this->data.resize(columns);
}

Row(const std::vector< Cell >& data) : data(data) {


}

void resize(size_t columns) {


data.resize(columns);
}
Cell& operator[](size_t column) {
return data[column];
}
const Cell& operator[](size_t column) const {
return data[column];
}
std::vector< Cell > toCellsVector() {
return this->data;
}
void pushCell(const Cell& value) {
data.push_back(value);
}
size_t getColumns() const {
return data.size();
}
};

class Matrix {
private:
std::vector< Row > data;
public:
Matrix(size_t rows, size_t columns): data(rows, Row(columns)) {
}
const Cell& get(size_t row, size_t col) const {
return data[row][col];
}
void set(size_t row, size_t col, Cell& value) {
data[row][col] = value;
}
const Row& getRow(size_t row) const {
return this->data[row];
}
void pushRow(const Row& row) {
data.push_back(row);
}
size_t getRows() const {
return this->data.size();
}
size_t getColumns() const {
if (this->getRows() == 0)
return 0;
else
return this->data[0].getColumns();
}
std::vector< Row > toRowsVector() {
return this->data;
}

Row& operator[](size_t row) {


return data[row];
}
const Row& operator[](size_t row) const {

Apendice F. Codigos Fuente 208


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

return data[row];
}
Matrix submatrixByRows(size_t rowIndexFrom, size_t rowIndexTo) {
Matrix result(rowIndexTo - rowIndexFrom + 1, this->getColumns());
size_t j = 0;
for(size_t i = rowIndexFrom; i <= rowIndexTo; ++i) {
result[j++] = this->data[i];
}
return result;
}
};
#endif

F.6.14. Parser.h

#ifndef PARSER__
#define PARSER__

#include <string>
#include <vector>
#include "Logger.h"
#include "Matrix.h"

class Parser {
private:
Logger& logger;
unsigned int probesCount;
void processLine(const std::string& line, unsigned int& currentStep, Row& probeValues);
Row readValuesForStep(const std::string& probesFilepath, unsigned int stepNumber);
Row readValuesWithRetry(const std::string& probesFilepath, unsigned int stepNumber, unsigned int retries)
;
public:
Parser(Logger& logger, unsigned int probesCount);
Row readValues(const std::string& probesFilepath, unsigned int stepNumber);
};

#endif

F.6.15. Parser.cpp

#include <iostream>
#include <fstream>
#include <sstream>
#include <limits>
#include <algorithm>
#include "Constants.h"
#include "Parser.h"

Parser::Parser(Logger& logger, unsigned int probesCount) : logger(logger), probesCount(probesCount) {


}

void Parser::processLine(const std::string& line, unsigned int& currentStep, Row& probeValues) {


unsigned int aux;
std::istringstream converter(line);
converter >> aux;

if (! converter.fail()) {
float auxTime;
converter >> auxTime;
currentStep = aux;
logger << "Parse successful. Step read: " << currentStep << std::endl;
for(int i = 0; i < this->probesCount; ++i) {

Apendice F. Codigos Fuente 209


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Cell value;
converter >> value;
probeValues[i] = value;
}
}
}

Row Parser::readValuesForStep(const std::string& probesFilepath, unsigned int stepNumber) {


Row probeValues(this->probesCount);
std::ifstream probes(probesFilepath.c_str());

probes.seekg(0, std::ios::beg);
std::ifstream::pos_type posBegin = probes.tellg();
probes.seekg(-1, std::ios::end);

unsigned int currentStep = std::numeric_limits<unsigned int>::max();


std::string line;
char buffer;
do {
buffer = probes.peek();

if (buffer != \n || probes.tellg() == posBegin)


line += buffer;
else {
std::reverse(line.begin(), line.end());
processLine(line, currentStep, probeValues);
line.clear();
}

probes.seekg(-1, std::ios::cur);
} while (probes.tellg() != posBegin && probes.good() && currentStep > stepNumber);

if (currentStep == stepNumber)
return probeValues;
else
throw "El archivo de muestras no posee el paso indicado. Posiblemente aon no fue escrito y se deba
reintentar.";
}

Row Parser::readValuesWithRetry(const std::string& probesFilepath, unsigned int stepNumber, unsigned int


retries) {
#define MAX_RETRIES 4
#define SECS_BETWEEN_RETRIES 5

try {
return readValuesForStep(probesFilepath, stepNumber);
}
catch(const char* msg) {
if (retries < MAX_RETRIES) {
sleep(SECS_BETWEEN_RETRIES);
logger << std::endl << "Step:" << stepNumber << " not found. Retrying parse: " << retries + 1 << std
::endl;
return readValuesWithRetry(probesFilepath, stepNumber, retries + 1);
}
else
throw;
}
}

Row Parser::readValues(const std::string& probesFilepath, unsigned int stepNumber) {


return readValuesWithRetry(probesFilepath, stepNumber, 0);
}

F.6.16. SaturneCommunicator.h

#ifndef SATURNE_COMMUNICATOR__

Apendice F. Codigos Fuente 210


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

#define SATURNE_COMMUNICATOR__

#include <iostream>
#include "Logger.h"

class SaturneCommunicator {
public:
int waitForStep(std::istream& semaphore, Logger& logger);
void send(std::ofstream& actuatorFile, Logger& logger, double value);
};

#endif

F.6.17. SaturneCommunicator.cpp

#include <sstream>
#include "SaturneCommunicator.h"

int SaturneCommunicator::waitForStep(std::istream& semaphore, Logger& logger) {


unsigned int semaphoreStepNumber;
logger << "Waiting..." << std::endl;
semaphore >> semaphoreStepNumber;
if (semaphore.good()) {
logger << " ...Signal received: " << semaphoreStepNumber << ". Resuming..." << std::endl;
return semaphoreStepNumber;
}
else {
logger << " ...File Closed or damaged. Resuming..." << std::endl;
return -1;
}
}

void SaturneCommunicator::send(std::ofstream& actuatorFile, Logger& logger, double value) {


std::stringstream converter;
converter << value;

std::string strValue;
converter >> strValue;
logger << "Sending " << strValue << "." << std::endl;
actuatorFile << strValue <<std::endl;
}

Apendice F. Codigos Fuente 211


G Codigos Fuente de Avances Experi-
mentales

G.1. Pruebas de Concepto de Captura de Imagenes


G.1.1. PixelFly qe

#define GAIN 1
#define DELAY 0 //ms
#define EXPOSURE_TIME 5 //ms
#define ROIX 2 //from 1 to 20
#define ROIY 2 //from 1 to 20

int main(int argc, char* argv[]) {


int totalSnapshots;

std::cout << "Qty of snapshots to take: ";


std::cin >> totalSnapshots;

int camId;
CAMINFO camData[8];
int boardNumber = 0;

int error;
if (error = SELECT_CAMERA("pixelfly", boardNumber, &camId, camData))
showErrorAndClose(error);
else {
if (error = SETUP_CAMERA(camId, camData, 0, 0, 0, 1, ROIX, 1, ROIY, 1, 1, GAIN, DELAY,
EXPOSURE_TIME))
showErrorAndClose(error);
else {
time_t beginTime, endTime;
time(&beginTime);

int snapshotNumber = 0;
while (! error && snapshotNumber < totalSnapshots) {
if (error = SNAP(camId, camData, 0))
showErrorAndClose(error);
else {
if (error = GETIMAGE(camId, camData, 2000))
showErrorAndClose(error);
else
// image in memory at this point
}
snapshotNumber++;
}
time(&endTime);
std::cout << std::endl << "Tiempo Promedio por imagen: " << 1000.0 * (double)difftime(endTime,
beginTime) / (float)totalSnapshots << "ms." << std::endl;
}
CLOSE_CAMERA(camId, camData);
}
return 0;
}

212
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

G.1.2. Pulnix

#include <cstdio>
#include <iostream>
#include "pxd.h"
#include "iframe.h"
#define IMAGEWIDTH 738
#define IMAGEHEIGHT 484

using namespace std;


int main(int argc, char* argv[])
{
PXD pxd;
FRAMELIB frameLib;
long hFG=0;
FRAME* pFRAME=0;
char arcFileName[20];
static int num=0;
int NO_FRAMES;

cout << "Ingrese el Nro de imagenes a capturar (30 fps)";


cin >> NO_FRAMES;

imagenation_OpenLibrary(".\\PXD_32.DLL", &pxd, sizeof(PXD));


imagenation_OpenLibrary (".\\frame_32.dll", &frameLib, sizeof(FRAMELIB));

CAMERA_TYPE *configInMem;

char configFile[] = {"default.cam"};


printf(" %s\n",configFile);
printf("Incio de Soft %d imagenes \n\n",NO_FRAMES);

hFG= pxd.AllocateFG (-1);

configInMem = pxd.LoadConfig(configFile); // load structure from file


pxd.SetCameraConfig(hFG,configInMem); // use the configuration file here
pxd.FreeConfig(configInMem);

pFRAME = pxd.AllocateBufferList (pxd.GetWidth(hFG), pxd.GetHeight(hFG), pxd.GetPixelType(hFG),NO_FRAMES);

printf("Incio de Captura %d imagenes \n\n",NO_FRAMES);


pxd.Grab (hFG, pFRAME,IMMEDIATE);

for(num= 0; num<NO_FRAMES ; num++) {


sprintf_s(arcFileName,"30fps %.3d.bmp", num);
printf(" %s \n",arcFileName);
frameLib.WriteBMP ( frameLib.ExtractPlane(pFRAME,num), arcFileName,1);
}
frameLib.FreeFrame (pFRAME);

pxd.FreeFG (hFG);
return 0;
}

G.1.3. SpeedCam Mini Vis

import com.artho.visart.plugins.minivis.internal.jni.MinivisFactory;
import com.artho.visart.util.TypedNetAddress;
import com.artho.visart.plugins.minivis.Proxy;
import com.artho.visart.plugins.minivis.internal.jni.CallbackConsumer;
import com.artho.visart.plugins.minivis.internal.jni.MDriverException;
import com.artho.visart.plugins.minivis.internal.jni.MFrameInfo;

class DummyConsumer implements CallbackConsumer {


public void modeChanged(int paramInt){
}

Apendice G. Codigos Fuente de Avances Experimentales 213


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

public void statusChanged(int paramInt) {


}
public void shutterChanged(boolean paramBoolean, short paramShort) {
}
}

public class Application {


public static void main(String[] arguments) {
System.out.println("Getting MinivisFactory...");
MinivisFactory factory = MinivisFactory.getInstance();
try {
System.out.println("Discovering cameras...");
factory.discover();

System.out.println("Getting known devices...");


TypedNetAddress[] addresses = factory.getKnownDevices();
System.out.println("Found " + addresses.length + " devices.");

System.out.println("Getting camera from MAC...");


DummyConsumer callbackConsumer = new DummyConsumer();
Proxy camera = factory.getCamera("MAC", callbackConsumer);

System.out.println("Connecting camera...");
camera.connect();

System.out.println("Triggering camera...");
camera.trigger();

System.out.println("Getting image...");
MFrameInfo frameInfo = new MFrameInfo();
byte[] frameBytes = camera.getFrame(-1, -1, frameInfo);
System.out.println("Get Frame result: " + frameInfo.width + "x" + frameInfo.height + " - " +
frameBytes.length + " bytes.");
}
catch(MDriverException e) {
e.printStackTrace();
}
}
}

G.2. Pruebas de Concepto de Ident. de Sist. en CUDA C/C++


y C++/GSL
Los archivos de codigo fuente que se adjuntan a continuacion, representan una prueba de
concepto sobre la posibilidad de implementar el algoritmo de identificacion del sistema en C++.
Para esta nueva version del sistema se utilizaron 2 libreras de algebra lineal con punto flotante de
doble precision: GSL y CUDA/CULA. En el ultimo caso se emplean las capacidades de GPGPU
del ordenador. Una comparacion de los resultados obtenidos se puede encontrar en el Apendice
C.2.

G.2.1. main.cpp

#include <iostream>
#include <sstream>
#include <fstream>
#include "common/CULAContext.h"
#include "common/Exception.h"
#include "common/Matrix.h"
#include "arxEngine/ArxSystemIdentification.h"

void readFromFile(const std::string& filepath, Matrix<t_sample>& target)

Apendice G. Codigos Fuente de Avances Experimentales 214


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

{
std::ifstream file(filepath.c_str());
if (file)
file >> target;
else
throw Exception("The file could not be opened for reading");
}

void writeToFile(const std::string& filepath, const Matrix<t_sample>& target)


{
std::ofstream file(filepath.c_str());
if (file)
file << target;
else
throw Exception("The file could not be opened for writing");
}

void calculate(int order, Matrix<t_sample>& input, Matrix<t_sample>& output, const std::string&


outputFolder)
{
ArxSystemIdentification arx(order, input, output);
arx.estimateModel();

std::string normalizedOutputFolder = outputFolder;


if (*outputFolder.rbegin() != / && *outputFolder.rbegin() != \\)
normalizedOutputFolder.append("\\");
for(int i = 0; i < order+1; ++i)
{
std::stringstream aFilepath, bFilepath;
aFilepath << normalizedOutputFolder << "A" << i << ".txt";
bFilepath << normalizedOutputFolder << "B" << i << ".txt";
writeToFile(aFilepath.str(), arx.getAModel(i));
writeToFile(bFilepath.str(), arx.getBModel(i));
}
}

int main(int argc, char* argv[])


{

if (argc != 8)
{
std::cout << "ArxGSL usage:" << std::endl;
std::cout << "ArxGSL.exe <arx-order> <samples-qty> <input samples-filepath> <input-components-dimension
> <output samples-filepath> <output-components-dimension> <output-folder>" << std::endl;
std::cout << "Output: A0.txt A1.txt B0.txt B1.txt will be written into the <output-folder>" << std::
endl;
return -1;
}
else
{
CULAContext context;
int order = atoi(argv[1]);
int samples = atoi(argv[2]);
char* uFilepath = argv[3];
int inputDim = atoi(argv[4]);
char* yFilepath = argv[5];
int outputDim = atoi(argv[6]);
char* outputFolder = argv[7];
try
{
context.init();
Matrix<t_sample> input(samples, inputDim);
Matrix<t_sample> output(samples, outputDim);
readFromFile(uFilepath, input);
readFromFile(yFilepath, output);
calculate(order, input, output, outputFolder);

return 0;
}
catch(const std::exception& ex)

Apendice G. Codigos Fuente de Avances Experimentales 215


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

{
std::cerr << "There was an unexpected error:" << ex.what() << std::endl;
return -1;
}
}
}

G.2.2. arxEngine/ArxSystemIdentification.h

#ifndef ARXSYSTEMIDENTIFICATION__H
#define ARXSYSTEMIDENTIFICATION__H

#include "../common/Matrix.h"
#include <vector>
typedef float t_sample;

class ArxSystemIdentification
{
private:
size_t order;
size_t m;
size_t r;
size_t samples;
const Matrix<t_sample>& input;
const Matrix<t_sample>& output;
std::vector< Matrix<t_sample> > estimatedA;
std::vector< Matrix<t_sample> > estimatedB;
public:
ArxSystemIdentification(int order, const Matrix<t_sample>& input, const Matrix<t_sample>& output);
void estimateModel();
const Matrix<t_sample>& getAModel(int index) const;
const Matrix<t_sample>& getBModel(int index) const;
};
#endif

G.2.3. arxEngine/ArxSystemIdentification.cpp

#include "ArxSystemIdentification.h"
#include "../common/Exception.h"

ArxSystemIdentification::ArxSystemIdentification(int order, const Matrix<t_sample>& input, const Matrix<


t_sample>& output)
:order(order), input(input), output(output)
{
this->m = output.getColumns();
this->r = input.getColumns();

if (output.getRows() != input.getRows())
throw Exception("Invalid dimensions. The input and output samples quantity should match");
else if (output.getRows() <= this->order + 1)
throw Exception("Not enough samples to compute the given order. The samples quantity should be higher
than the order plus 1.");
else
this->samples = output.getRows();
}

void ArxSystemIdentification::estimateModel()
{
/* Model definition:
y(k)+a_1*y(k-1)+a_2*y(k-2)+...a_na*y(k-na) = b_1*u(k)+b_2*u(k-1)+...+b_nb*u(k-(nb-1))

where

Apendice G. Codigos Fuente de Avances Experimentales 216


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

y(k) is the output at time k with dimension m x 1.


u(k) is the input at time k with dimension r x 1.
a_1,..a_na matrices of m x m
b_1,...b_nb matrices of m x r

The algorithm will consider na = nb-1 and N=qty of samples.


*/

size_t na = this->order;
size_t nb = na + 1;
size_t N = this->samples;

/*
Let y : mxN / j-th column has the j-th time sample.
Let u : rxN / j-th column has the j-th time sample.
*/
Matrix<t_sample> y = this->output.transpose();
Matrix<t_sample> u =this->input.transpose();

/*
Let fi : na*m+nb*r x N -> Regresion vector for k time step being:
/ fi(k column) = [-y(k-1 to k-na time samples); u(k to k-(nb-1) time samples)]
= [-y(:,k-1); ...;-y(:,k-na);u(:,k);u(:,k-1);...;u(:,k-(nb-1))]
when k in [na+1,N] = [nb,N]
/ fi(k colum = [0; ... ; 0] when k in [1,na] = [1,nb-1]
*/

Matrix<t_sample> fi(na*m+nb*r, N, true);


// fi should take na columns of y and nb columns from u in order to create one single column.
// fi will take N columns as above but slicing the y and u column indexes each.
for(size_t fiColumn = na; fiColumn < N; ++fiColumn) {
size_t fiRow = 0;
int columnOffset = fiColumn - (int)na;
//iterates columns na-1 to 0 for fiColumn=na and N-2 to N-na-1 for fiColumn=N-1
for(int yColumn = na - 1 + columnOffset; yColumn >= 0 + columnOffset; --yColumn) {
for(size_t yRow = 0; yRow < m; ++yRow) {
fi.set(fiRow, fiColumn, -y.get(yRow, yColumn));
++fiRow;
}
}

//iterates columns nb-1 to 0 for fiColumn=na and N-1 to N-na-1=N-nb for fiColumn=N-1
for(int uColumn = nb - 1 + columnOffset; uColumn >= 0 + columnOffset; --uColumn) {
for(size_t uRow = 0; uRow < r; ++uRow) {
fi.set(fiRow, fiColumn, u.get(uRow, uColumn));
++fiRow;
}
}
}

/*
Let reg: m*(na*m+nb+r) x m*(N-na) -> Regresion matrix
reg(k to column block) = [fi(1,na+1 + (k-1))*eye(m); fi(2,na+1 + (k-1))*eye(m);...; fi(na*m+nb*r, na
+1 + (k-1))*eye(m)] when k in [1,N-na]

and

Y = reshape(y(:, na+1:end), m*(N-na), 1);


*/
Matrix<t_sample> reg(m*(na*m+nb*r), m*(N-na), true);
for(size_t kBlock = 0; kBlock < N-na; ++kBlock) {
//fiColumn from na to N-1
size_t fiColumn = kBlock+na;
for(size_t fiRow = 0; fiRow < (na*m+nb*r); ++fiRow) {
t_sample value = fi.get(fiRow, fiColumn);
for(size_t iBlock = 0; iBlock < m; ++iBlock) {
reg.set(fiRow * m + iBlock, kBlock * m + iBlock, value);
}

Apendice G. Codigos Fuente de Avances Experimentales 217


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

}
}

Matrix<t_sample> Y(m*(N-na),1);
for(size_t yColumn = na; yColumn < N; ++yColumn) {
for(size_t yRow = 0; yRow < m; ++yRow) {
Y.set((yColumn-na)*m + yRow, 0, y.get(yRow, yColumn));
}
}

/*
Let F: m*(N-na) x m*(na*m+nb*r)+1)
F = [reg Y]
*/
Matrix<t_sample> F(m*(N-na), m*(na*m+nb*r)+1);
for(size_t regRow = 0; regRow < m*(na*m+nb*r); ++regRow) {
for(size_t regCol = 0; regCol < m*(N-na); ++regCol) {
F.set(regCol, regRow, reg.get(regRow, regCol));
}
}
for(size_t yRow = 0; yRow < m*(N-na); ++yRow) {
F.set(yRow, m*(na*m+nb*r), Y.get(yRow, 0));
}

/*
Compute the QR decomposition of F and keep the R part.
Then, collect R1 and R2 according to:
R1 = R(1:d, 1:d);
R2 = R(1:d, 1:d+1);
being d = na*m*m+nb*r*m
*/
int d = na*m*m+nb*r*m;
Matrix<t_sample> qr = F.decomposeQRGsl();
Matrix<t_sample> rDecomp = qr.getTriu();
Matrix<t_sample> r1 = rDecomp.getSubmatrix(0, 0, d-1, d-1);
Matrix<t_sample> r2 = rDecomp.getSubmatrix(0, d, d-1, d);

/*
Then, we disregard Q part and unnecesary R values to estimate the A and B coefficients:
th = pinv(R1) * R2;
*/
Matrix<t_sample> th = r1.invert().multiply(r2);

/*
Collect the A and B parameters from within th
*/
Matrix<t_sample> A0(m, m, true);
for(size_t i = 0; i < m; ++i)
{
A0.set(i,i,1);
}
this->estimatedA.push_back(A0);
for(size_t k = 0; k < na; ++k)
{
//Take the submatrix as per: a(:,:,j)=reshape(th(1+(j-1)*m*m:j*m*m),m,m);
Matrix<t_sample> Ak = th.getRow(k*m*m, (k+1)*m*m-1);
this->estimatedA.push_back(Ak.reshape(m,m));
}

for(size_t k = 0; k < nb; ++k)


{
//Take the submatrix as per: b(:,:,j)=reshape(th(1+na*m*m+(j-1)*m*r:1+na*m*m+(j-1)*m*r+m*r-1),m,r);
Matrix<t_sample> Bk = th.getRow(na*m*m + k*m*r, na*m*m + (k+1)*m*r - 1);
this->estimatedB.push_back(Bk.reshape(m,r));
}
}

const Matrix<t_sample>& ArxSystemIdentification::getAModel(int index) const


{

Apendice G. Codigos Fuente de Avances Experimentales 218


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

return this->estimatedA.at(index);
}

const Matrix<t_sample>& ArxSystemIdentification::getBModel(int index) const


{
return this->estimatedB.at(index);
}

/*
Source code in Matlab:

y = y;
u = u;

na = p;
nb = na+1;
%Modelo de partida:
% y(k)+a_1*y(k-1)+a_2*y(k-2)+...a_na*y(k-na)=
% =b_1*u(k)+b_2*u(k-1)+...+b_nb*u(k-(nb-1))
%donde
% y(k) es la salida en el tiempo k, vector de mx1
% u(k) es la entrada en el tiempo k, vector de rx1
% a_1,..a_na matrices de mxm
% b_1,...b_nb matrices de mxr
%venimos considerando na=nb-1
%De acuerdo con esta escritura, se considera
% N:cantidad de observaciones
% y: matriz de observaciones de las salidas, de mxN; es decir, en la
%columna j la salida en el tiempo j
% u: matriz de las observaciones de las entradas, de rxN; es decir, en la columna j la entrada en el
tiempo j

%segon Ljung, se define el vector de regresion en el tiempo k como:


% fi(k)=(-y(k-1), ...,-y(k-na),u(k), u(k-1),...u(k-(nb-1))
% y el "vector" de parometros a calcular mp=(a_1,...,a_na,_1,...b_nb)

[m,N] = size(y);
[r,N] = size(u);

%se construye fi con los valores de regresion, considerando los tiempos de


%na+1 en adelante
fi = zeros(na*m+nb*r,N);
for j=na+1:N
fi(:,j)=[reshape(-y(:, j-1:-1:j-na), na*m, 1); ...
reshape(u(:, j:-1:j-(nb-1)), nb*r, 1)];
end

%se construye la matriz de regresion


fi2 = fi(:, na+1:end);
reg = zeros(m*size(fi2,1), m*(N-na));
for j=1:N-na
reg(:, 1+(j-1)*m:j*m) = kron(fi2(:,j), eye(m));
end

%REVISAR SIG LINEA


yna = y(:, na+1:end);
Y = reshape(yna, m*(N-na), 1);

F = [reg Y];
R = triu(qr(F));

%d: cantidad de nomeros a determinar para armar las matrices %del modelo
d = na*m*m+nb*r*m;
R0 = R(1:d+1,1:d+1);
R1 = R0(1:d,1:d);
R2 = R0(1:d,end);

Apendice G. Codigos Fuente de Avances Experimentales 219


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

%se desecha la parte Q de la matriz F y se resuelve por cuad. monimos


%th: resultante que contiene los valores para armar las matrices A y B
th = pinv(R1) * R2;

a = zeros(m, m, na);
b = zeros(m, r, nb);
for j=1:na
a(:,:,j)=reshape(th(1+(j-1)*m*m:j*m*m),m,m);
end
for j=1:nb
b(:,:,j)=reshape(th(1+na*m*m+(j-1)*m*r:1+na*m*m+(j-1)*m*r+m*r-1),m,r);
end

A = zeros(m, m, na+1);
A(:,:,1) = eye(m);
A(:,:,2:end) = a(:,:,:);
B = b;

*/

G.2.4. common/Matrix.h

#ifndef MATRIX__H
#define MATRIX__H

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <exception>
#include <cstring>
#include "../common/Exception.h"
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_permutation.h>
#include <gsl/gsl_blas_types.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_blas.h>
#include <cula_lapack.h>
#include <cula_blas.h>

#define GSL_DLL
#define PRINT_MATRIX_CELL_VALUE_PRECISION 10
#define MINIMUN_ACCEPTED_EIGENVALUE_ON_SVD 0.000001

template < typename T = float>


class Matrix
{
private:
gsl_matrix* inner;
size_t rows;
size_t columns;
public:
Matrix(size_t rows, size_t columns, bool defaultToZero = false)
:rows(rows), columns(columns)
{
if (defaultToZero)
inner = gsl_matrix_calloc(rows, columns);
else
inner = gsl_matrix_alloc(rows, columns);
}

Matrix(const Matrix<T>& toCopy)


:rows(toCopy.rows), columns(toCopy.columns)
{

Apendice G. Codigos Fuente de Avances Experimentales 220


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

inner = gsl_matrix_alloc(rows, columns);


gsl_matrix_memcpy(inner, toCopy.inner);
}
Matrix(gsl_matrix* matrix, bool manageMemory)
:rows(matrix->size1), columns(matrix->size2)
{
if (manageMemory) {
inner = matrix;
}
else {
inner = gsl_matrix_alloc(rows, columns);
gsl_matrix_memcpy(inner, matrix);
}
}

Matrix<T>& operator=(const Matrix<T>& toCopy)


{
if (this != &toCopy)
{
gsl_matrix_free(inner);
this->rows = toCopy.rows;
this->columns = toCopy.columns;
inner = gsl_matrix_alloc(rows, columns);
gsl_matrix_memcpy(inner, toCopy.inner);
}
return *this;
}

Matrix<T> reshape(size_t newRows, size_t newColumns) const


{
if (newRows*newColumns != this->rows*this->columns)
{
std::stringstream message;
message << "It is not possible to reshape a " << this->rows << "x" << this->columns << " to a " <<
newRows << "x" << newColumns << " matrix. Amount of elements should match.";
throw Exception(message.str().c_str());
}
Matrix<T> newShape(newRows, newColumns);
size_t iNew = 0;
size_t jNew = 0;
for(size_t j = 0; j < this->columns; ++j)
{
for(size_t i = 0; i < this->rows; ++i)
{
newShape.set(iNew, jNew, this->get(i,j));
if (iNew == newRows - 1)
{
iNew = 0;
++jNew;
}
else
++iNew;

}
}
return newShape;
}

Matrix<T> transpose() const


{
gsl_matrix* transposed = gsl_matrix_alloc(this->columns, this->rows);
gsl_matrix_transpose_memcpy(transposed, inner);
return Matrix<T>(transposed, true);
}

Matrix<T> getTriu() const


{
Matrix<T> triu(this->rows, this->columns, true);
for(size_t i = 0; i < this->rows; ++i)
{

Apendice G. Codigos Fuente de Avances Experimentales 221


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

for(size_t j = i; j < this->columns; ++j)


{
triu.set(i,j, this->get(i,j));
}
}
return triu;
}
Matrix<T> decomposeQRCULA() const
{
int lda = this->rows;
int matrixRank = this->rows > this->columns? this->columns: this->rows;
Matrix<T> transposed = this->transpose();
T* aCula = transposed.toArrayRowMajor();
T* tauCula = (T*) malloc(matrixRank*sizeof(T));

culaStatus status = culaSgeqrf(this->rows, this->columns, aCula, lda, tauCula);


checkStatus(status);

Matrix<T> resultTransposed(this->columns, this->rows);


resultTransposed.fromArrayRowMajor(aCula);

free(aCula);
free(tauCula);

return resultTransposed.transpose();
}

Matrix<T> decomposeQRGsl() const


{
int matrixRank = this->rows > this->columns? this->columns: this->rows;

gsl_matrix* copy = gsl_matrix_alloc(this->rows, this->columns);


gsl_matrix_memcpy(copy, inner);
gsl_vector* tau = gsl_vector_alloc(matrixRank);
gsl_linalg_QR_decomp (copy, tau);
gsl_vector_free(tau);

return Matrix<T>(copy, true);


}
Matrix<T> pseudoInvertCULA()
{
//A = U S V^T where U:mxm, S:mxn, V:nxn
Matrix<T> transposed = this->transpose();

int lda = this->rows;


int ldu = this->rows;
int ldvt = this->columns;
int matrixRank = this->rows > this->columns? this->columns: this->rows;
T* aCula = transposed.toArrayRowMajor();
T* sCula = (T*) malloc(matrixRank*sizeof(T));
T* uCula = (T*) malloc(ldu*this->rows*sizeof(T)); //[u] = mxm
T* vtCula = (T*) malloc(ldvt*this->columns*sizeof(T)); //[v] = nxn

//char jobu, char jobvt, int m, int n, culaFloat* a, int lda, culaFloat* s, culaFloat* u, int ldu,
culaFloat* vt, int ldvt);
//culaStatus status = culaSgesvd(A, A, this->rows, this->columns, aCula, lda, sCula, uCula, ldu,
vtCula, ldvt);
culaStatus status = culaSgesvd(A, A, this->rows, this->columns, aCula, lda, sCula, uCula, ldu,
vtCula, ldvt);
checkStatus(status);

//Inverting S//
//----------------------------------------------------------
// Matrix S is diagonal, so it is contained in a vector. We operate to convert the vector S
//----------------------------------------------------------

//sInv should be columns x rows -> use transposed order for cula having columns qty of elements per
memory row
T* sInvCula = (T*)calloc(this->rows*this->columns*sizeof(T), true);

Apendice G. Codigos Fuente de Avances Experimentales 222


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

for (size_t i = 0; i < matrixRank; i++) {


if (*(sCula+i) > MINIMUN_ACCEPTED_EIGENVALUE_ON_SVD)
*(sInvCula+i*this->columns+i) = 1.0 / *(sCula+i);
}

//THE PSEUDOINVERSE//
//----------------------------------------------------------
//Computation of the pseudoinverse of A as pinv(A) = V.pinv(S).trans(U)[nxn.nxm.mxm=nxm]
//----------------------------------------------------------
Matrix<T> pInvT(this->rows, this->columns);
T* sInvUtCula = multiplyCULANoneTransposed(sInvCula, uCula, this->columns, this->rows, this->rows, this
->rows);
T* pInvCula = multiplyCULATransposedNone(vtCula, sInvUtCula, this->columns, this->columns, this->
columns, this->rows);

free(aCula);
free(sCula);
free(uCula);
free(vtCula);
free(sInvUtCula);
pInvT.fromArrayRowMajor(pInvCula);
free(pInvCula);
return pInvT.transpose();
}

Matrix<T> pseudoInvertGsl()
{
//A = U S V^T where U:mxn, S:nxn, V:nxn
gsl_matrix * U = gsl_matrix_alloc (this->rows, this->columns); //[u] = mxn
gsl_matrix * V = gsl_matrix_alloc (this->columns, this->columns); //[v] = nxn
gsl_vector * S = gsl_vector_alloc (this->columns); //[s] = n

// Computing the SVD of A


// The variable U should contain A as input and U as output.
gsl_matrix_memcpy(U, this->inner);
gsl_vector * work = gsl_vector_alloc (this->columns);
gsl_linalg_SV_decomp (U, V, S, work);
gsl_vector_free(work);

//Inverting S//
// Matrix S is diagonal, so it is contained in a vector.
// We operate to convert the vector S into the matrix SI.
gsl_matrix * SI = gsl_matrix_calloc (this->columns, this->columns);

for (size_t i = 0; i < this->columns; i++) {


if (gsl_vector_get (S, i) > MINIMUN_ACCEPTED_EIGENVALUE_ON_SVD)
gsl_matrix_set (SI, i, i, 1.0 / gsl_vector_get (S, i));
}

//THE PSEUDOINVERSE//
//----------------------------------------------------------
//Computation of the pseudoinverse of A as pinv(A) = V.pinv(S).trans(U)[nxn.nxn.nxm=nxm]
//----------------------------------------------------------
gsl_matrix * SIpUT = multiplyGslNoneTransponsed(SI, U); //[SIpUT] = nxm
gsl_matrix * pinv = multiplyGslNoneNone(V, SIpUT); //[pinv] = nxm

gsl_matrix_free(SI);
gsl_matrix_free(SIpUT);
gsl_matrix_free(V);
gsl_vector_free(S);
return Matrix<T>(pinv, true);
}

Matrix<T> invert()
{
if (this->rows != this->columns)
throw Exception("It is not possible to invert a non square matrix.");

Apendice G. Codigos Fuente de Avances Experimentales 223


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

int matrixRank = this->rows;

gsl_matrix *matrixCopy = gsl_matrix_alloc(matrixRank, matrixRank);


gsl_matrix_memcpy(matrixCopy, inner);

gsl_matrix *inverse = gsl_matrix_alloc(matrixRank, matrixRank);


gsl_permutation* p = gsl_permutation_alloc(matrixRank);
int s=0;
gsl_linalg_LU_decomp (matrixCopy, p, &s);
gsl_linalg_LU_invert(matrixCopy,p,inverse);

gsl_matrix_free(matrixCopy);
gsl_permutation_free(p);

return Matrix<T>(inverse, true);


}

Matrix<T> sum(const Matrix<T>& toSum) const


{
if (toSum.columns != columns) {
std::stringstream message;
message << "Invalid column size for sum operation. Left matrix cols: " << columns << ". right matrix
cols: " << toSum.getColumns();
throw Exception(message.str().c_str());
}
if (toSum.rows != rows) {
std::stringstream message;
message << "Invalid row size for sum operation. Left matrix rows: " << rows<< ". right matrix rows: "
<< toSum.getRows();
throw Exception(message.str().c_str());
}
gsl_matrix* result = gsl_matrix_alloc(this->rows, this->columns);
gsl_matrix_memcpy(result, inner);
gsl_matrix_add(result, toSum.inner);
return Matrix<T>(result, true);
}

Matrix<T> multiply(const Matrix<T>& toMultiply) const


{
if (toMultiply.getRows() != columns) {
std::stringstream message;
message << "Invalid rows size for multiply operation. Left matrix dimension: " << rows << "x" <<
columns << ". Right matrix dimension: " << toMultiply.getRows() << "x" << toMultiply.getColumns()
;
throw Exception(message.str().c_str());
}

Matrix<T> multiplyResult(this->rows, toMultiply.getColumns());


for(size_t i = 0; i < this->rows; ++i)
{
for(size_t j = 0; j < toMultiply.getColumns(); ++j)
{
T cellValue = 0;
for(size_t k = 0; k < this->columns; ++k)
{
cellValue += this->get(i, k) * toMultiply.get(k, j);
}
multiplyResult.set(i, j, cellValue);
}
}
return multiplyResult;
}

Matrix<T> multiplyCULA(const Matrix<T>& toMultiply) const


{
if (this->columns != toMultiply.rows) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << this->columns << ".
right matrix rows: " << this->columns;

Apendice G. Codigos Fuente de Avances Experimentales 224


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

throw Exception(message.str().c_str());
}
T* atCula = this->toArrayRowMajor();
T* btCula = toMultiply.toArrayRowMajor();
T* resultTCula = multiplyCULATransposedTransposed(atCula, btCula, this->columns, this->rows, toMultiply
.columns, toMultiply.rows);
Matrix<T> resultT(toMultiply.columns, this->rows);
resultT.fromArrayRowMajor(resultTCula);
return resultT.transpose();
}

Matrix<T> multiplyGsl(const Matrix<T>& toMultiply) const


{
if (this->columns != toMultiply.rows) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << this->columns << ".
right matrix rows: " << this->columns;
throw Exception(message.str().c_str());
}
gsl_matrix* result = multiplyGslNoneNone(this->inner, toMultiply.inner);
return Matrix<T>(result, true);
}

Matrix<T> divide(T denominator) const


{
Matrix<T> divisionResult(this->rows, this->columns);
for(size_t i = 0; i < this->rows; ++i)
{
for(size_t j = 0; j < this->columns; ++j)
{
divisionResult.set(i, j, this->get(i, j) / denominator);
}
}
return divisionResult;
}

Matrix<T> getSubmatrix(size_t rowFrom, size_t columnFrom, size_t rowTo, size_t columnTo) const
{
this->validateRow(rowFrom);
this->validateColumn(columnFrom);
this->validateRow(rowTo);
this->validateColumn(columnTo);
if (rowFrom > rowTo || columnFrom > columnTo) {
std::stringstream message;
message << "Invalid column range. Row/Column From should be less than row/column to. RowFrom: " <<
rowFrom << ". ColumnFrom: " << columnFrom << ". RowTo: " << rowTo << ". ColumnTo: " << columnTo;
throw Exception(message.str().c_str());
}

Matrix<T> submatrix(rowTo - rowFrom + 1, columnTo - columnFrom + 1);


for(size_t column = columnFrom; column <= columnTo; ++column)
{
for(size_t row = rowFrom; row <= rowTo; ++row)
{
submatrix.set(row - rowFrom, column - columnFrom, this->get(row, column));
}
}
return submatrix;
}

Matrix<T> getColumn(size_t columnFrom, size_t columnTo) const


{
return this->getSubmatrix(0, columnFrom, this->rows-1, columnTo);
}

Matrix<T> getColumn(size_t column) const


{
return this->getColumn(column, column);

Apendice G. Codigos Fuente de Avances Experimentales 225


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

Matrix<T> getRow(size_t rowFrom, size_t rowTo) const


{
return this->getSubmatrix(rowFrom, 0, rowTo, this->columns-1);
}

Matrix<T> getRow(size_t row) const


{
return this->getRow(row, row);
}

~Matrix()
{
gsl_matrix_free(inner);
}
size_t getRows() const
{
return rows;
}
size_t getColumns() const
{
return columns;
}
T get(size_t row, size_t column) const
{
validateCell(row, column);
return gsl_matrix_get(inner, row, column);
}
void set(size_t row, size_t column, T value)
{
validateCell(row, column);
return gsl_matrix_set(inner, row, column, value);
}

T* toArrayRowMajor() const
{
T* array = (T*)malloc(this->rows*this->columns*sizeof(T));
for(size_t i = 0; i < this->rows; ++i){
//memcpy(array + i*this->columns, inner->data + i * inner->tda, this->columns*sizeof(T));
for(size_t j = 0; j < this->columns; ++j){
*(array + i*this->columns + j) = (T)(*(inner->data + i * inner->tda + j));
}
}

return array;
}

void fromArrayRowMajor(const T* array) const


{
for(size_t i = 0; i < this->rows; ++i){
//memcpy(inner->data + i * inner->tda, array + i*this->columns, this->columns*sizeof(T));
for(size_t j = 0; j < this->columns; ++j){
*(inner->data + i * inner->tda + j) = (double)(*(array + i*this->columns + j));
}
}
}
private:
void validateCell(size_t row, size_t column) const
{
this->validateRow(row);
this->validateColumn(column);
}

void validateColumn(size_t column) const


{
if (column < 0 || column >= columns) {
std::stringstream message;
message << "Invalid column index. Total Cols: " << columns << ". Asked: " << column;
throw Exception(message.str());

Apendice G. Codigos Fuente de Avances Experimentales 226


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

}
}

void validateRow(size_t row) const


{
if (row < 0 || row >= rows) {
std::stringstream message;
message << "Invalid row index. Total Rows: " << rows << ". Asked: " << row;
throw Exception(message.str());
}
}

void checkStatus(culaStatus status) const


{
if(status)
{
char buf[256];
culaGetErrorInfoString(status, culaGetErrorInfo(), buf, sizeof(buf));
throw Exception(buf);
}
}
T* multiplyCULATransposedNone(T* aCula, T* bCula, int mA, int nA, int mB, int nB) const
{
if (mA != mB) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << mA << ". right matrix
rows: " << mB;
throw Exception(message.str().c_str());
}

return blasMultiplyCULA(aCula, T, bCula, N, nA, nB, mA, mA, mA);


}

T* multiplyCULANoneTransposed(T* aCula, T* bCula, int mA, int nA, int mB, int nB) const
{
if (nA != nB) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << nA << ". right matrix
rows: " << nB;
throw Exception(message.str().c_str());
}

return blasMultiplyCULA(aCula, N, bCula, T, mA, mB, nA, mA, mB);


}

T* multiplyCULATransposedTransposed(T* aCula, T* bCula, int mA, int nA, int mB, int nB) const
{
if (mA != nB) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << mA << ". right matrix
rows: " << nB;
throw Exception(message.str().c_str());
}
return blasMultiplyCULA(aCula, T, bCula, T, nA, mB, mA, mA, mB);
}

T* multiplyCULANoneNone(T* aCula, T* bCula, int mA, int nA, int mB, int nB) const
{
if (nA != mB) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << nA << ". right matrix
rows: " << mB;
throw Exception(message.str().c_str());
}

return blasMultiplyCULA(aCula, N, bCula, N, mA, nB, nA, mA, nA);


}
gsl_matrix* multiplyGslTransposedNone(gsl_matrix* a, gsl_matrix* b) const
{
if (a->size1 != b->size1) {

Apendice G. Codigos Fuente de Avances Experimentales 227


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << a->size1 << ". right
matrix rows: " << b->size1;
throw Exception(message.str().c_str());
}
return blasMultiplyGsl(a, b, CblasTrans, CblasNoTrans, a->size2, b->size1);
}
gsl_matrix* multiplyGslNoneTransponsed(gsl_matrix* a, gsl_matrix* b) const
{
if (a->size2 != b->size2) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << a->size2 << ". right
matrix rows: " << b->size2;
throw Exception(message.str().c_str());
}
return blasMultiplyGsl(a, b, CblasNoTrans, CblasTrans, a->size1, b->size1);
}
gsl_matrix* multiplyGslNoneNone(gsl_matrix* a, gsl_matrix* b) const
{
if (a->size2 != b->size1) {
std::stringstream message;
message << "Invalid row size for multiply operation. Left matrix columns: " << a->size2 << ". right
matrix rows: " << b->size1;
throw Exception(message.str().c_str());
}
return blasMultiplyGsl(a, b, CblasNoTrans, CblasNoTrans, a->size1, b->size2);
}

gsl_matrix* blasMultiplyGsl(gsl_matrix* a, gsl_matrix* b, CBLAS_TRANSPOSE_t opA, CBLAS_TRANSPOSE_t opB,


size_t responseRows, size_t responseCols) const
{
gsl_matrix * r = gsl_matrix_alloc (responseRows, responseCols);
gsl_blas_dgemm (opA, opB,
1.0, a, b,
0.0, r);
return r;
}

/**
* T* blasMultiplyCULA(T* aCula, char opA, T* bCula, char opB, int m, int n, int k, int lda, int ldb)
* */
T* blasMultiplyCULA(T* aCula, char opA, T* bCula, char opB, int m, int n, int k, int lda, int ldb) const
{
T* cCula = (T*) malloc(m*n*sizeof(T));
//culaStatus culaSgemm(char transa, char transb, int m, int n, int k, culaFloat alpha, culaFloat* a,
int lda, culaFloat* b, int ldb, culaFloat beta, culaFloat* c, int ldc);
//C := alpha*op(A)*op(B)+beta*C, where op=[N(none), T(transposed), C(conjugate)]
culaStatus status = culaSgemm(opA, opB, m, n, k, 1, aCula, lda, bCula, ldb, 0, cCula, m);
checkStatus(status);
return cCula;
}
};

template <typename T>


std::istream& operator>>(std::ifstream& input, Matrix<T>& matrix)
{
for(size_t j = 0; j < matrix.getColumns(); ++j)
{
for(size_t i = 0; i < matrix.getRows(); ++i)
{
T cellValue;
input >> std::setiosflags(std::ios::fixed) >> std::setprecision(PRINT_MATRIX_CELL_VALUE_PRECISION) >>
cellValue;
matrix.set(i, j, cellValue);
if (! input.good())
throw Exception("Error writing the matrix file");
}
}

Apendice G. Codigos Fuente de Avances Experimentales 228


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

return input;
}

template <typename T>


std::ostream& operator<<(std::ostream& output, const Matrix<T>& matrix)
{
for(size_t j = 0; j < matrix.getColumns(); ++j)
{
for(size_t i = 0; i < matrix.getRows(); ++i)
{
T cellValue = matrix.get(i, j);
output << std::setiosflags(std::ios::fixed) << std::setprecision(PRINT_MATRIX_CELL_VALUE_PRECISION)
<< cellValue << " ";
if (! output.good())
throw Exception("Error writing the matrix file");
}
output << std::endl;
}
return output;
}

#endif

G.2.5. common/CULAContext.h

#ifndef CULACONTEXT_H_
#define CULACONTEXT_H_
#include <cula_lapack.h>

class CULAContext {
public:
CULAContext();
void init();
virtual ~CULAContext();
private:
void checkMinimumCulaRequirements();
void checkStatus(culaStatus status);
};

#endif /* CULACONTEXT_H_ */

G.2.6. common/CULAContext.cpp

#include "CULAContext.h"
#include "Exception.h"
#include <sstream>

CULAContext::CULAContext() {
culaStatus status = culaInitialize();
checkStatus(status);
}
void CULAContext::init() {
this->checkMinimumCulaRequirements();
}

CULAContext::~CULAContext() {
culaShutdown();
}

void CULAContext::checkMinimumCulaRequirements()
{
std::stringstream errorMessage;

Apendice G. Codigos Fuente de Avances Experimentales 229


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

int cudaMinimumVersion = culaGetCudaMinimumVersion();


int cudaRuntimeVersion = culaGetCudaRuntimeVersion();
int cudaDriverVersion = culaGetCudaDriverVersion();
int cublasMinimumVersion = culaGetCublasMinimumVersion();
int cublasRuntimeVersion = culaGetCublasRuntimeVersion();
int errors = 0;
if(cudaRuntimeVersion < cudaMinimumVersion)
{
errorMessage << "CUDA runtime version is insufficient; version " << cudaMinimumVersion << " or greater
is required" << std::endl;
++errors;
}
if(cudaDriverVersion < cudaMinimumVersion)
{
errorMessage << "CUDA driver version is insufficient; version " << cudaMinimumVersion << " or greater
is required" << std::endl;
++errors;
}
if(cublasRuntimeVersion < cublasMinimumVersion)
{
errorMessage << "CUBLAS runtime version is insufficient; version " << cublasMinimumVersion << " or
greater is required" << std::endl;
++errors;
}
if (errors)
throw Exception(errorMessage.str());
}

void CULAContext::checkStatus(culaStatus status)


{
char buf[256];
if(status){
culaGetErrorInfoString(status, culaGetErrorInfo(), buf, sizeof(buf));
throw Exception(buf);
}
}

G.2.7. common/Exception.h

#ifndef EXCEPTION_H_
#define EXCEPTION_H_

#include <string>
#include <exception>

class Exception : public std::exception {


private:
std::string message;
public:
Exception(const std::string& message);
virtual ~Exception() throw() {}
virtual const char* what() const throw();
};

#endif /* EXCEPTION_H_ */

G.2.8. common/Exception.cpp

#include "Exception.h"

Exception::Exception(const std::string& message) : message(message) {


}

Apendice G. Codigos Fuente de Avances Experimentales 230


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

const char* Exception::what() const throw() {


return this->message.c_str();
}

G.3. Pruebas de Concepto de Controlador Adaptativo


G.3.1. lfd control init.m

function [ control_state ] = lfd_control_init(y, u, p, alpha, mu, A, B, limits, q)


% usage example:
%
% [A, B] = lfd_arx(y, u, 2);
% limits.min_value = 0;
% limits.max_value = 3;
% control_state = lfd_control_init(y, u, 2, 0.99999, 1/625000, A, B, limits, ones(1,sizeof(y,2)));
% next_actuation = lfd_control(control_state, y, u);

y = y;
u = u;

%y de m*N datos de las salidas


%u de r*N datos de entradas, N=cantidad de observaciones
%p=orden del modelo ARX

if size(y,2) ~= size(u,2)
error(lfd_control:input,Unable to determine current time step number: k. Samples in y(count: %d) and u(
count: %d) do not match, size(y,2), size(u,2));
end
k = size(y,2);

%m=cantidad de componentes de y
%r=cantidad de componentes de u
m = size(y,1);
r = size(u,1);

%alfa=0.999999, mu, parametros de Kegerise


g=(1-alpha)/mu; %g=gamma otro de los parametros de Kegerise
%alfa=0.999999=1-2*g*mu

%s=horizonte de prediccion (valores recomendados entre 2 y 3 veces p)


s=2*p;

control_state.p = p;
control_state.alpha = alpha;
control_state.mu = mu;
control_state.limits = limits;
control_state.s = s;
control_state.m = m;
control_state.r = r;
control_state.g = g;
control_state.k = k;

%k indica el paso a partir del cual se aplica el control; debe ser k-p-s >=1,
%k-s>=1
if k-p-s < 1
error(lfd_control:k_validation, Arguments error. TimeStep, Order and PredictionHorizon should match
the following rule: k-p-s>=1. k: %d,p: %d,s: %d., k_last_computation, p, s);
end

%segun la idea de Kegerise se busca min y_sQy_s+g tr(HH)


%Q es diagonal en bloques, de msxms, con bloques diagonales
%Q_1,..Q_s de tamanios mxm, con numeros entre 0 y 1 en la diagonal
%Cada Q_i=diag(q_1(i),..q_m(i))

Apendice G. Codigos Fuente de Avances Experimentales 231


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

%el termino y_sQy_s se puede leeer:


%y(k)Q_1y(k)+y(k+1)Q_2y(k+1)+...y(k+s-1)Q_sy(k+s-1)

%Se define q=vector de m componentes para indicar el peso para cada componente.
%Se forma TQ; se necesitan onicamente las primeras r filas de TQ usando la notacion de Juang
%por lo tanto no es necesario computar Q completa. Donde se supone Q=diag(repmat(q,1,s));

A=-A(:,:,2:end);
beta00=B(:,:,1);

beta0(:,:,1)=B(:,:,2)+A(:,:,1)*beta00;

for kk=2:s-1;
if kk<=p;
aux=zeros(size(beta00));for l=1:kk-1;aux=aux+A(:,:,l)*beta0(:,:,kk-l);end;aux=aux+A(:,:,kk)*beta00;
beta0(:,:,kk)=B(:,:,kk+1)+aux;
else
aux=zeros(size(beta00));for l=1:p;aux=aux+A(:,:,l)*beta0(:,:,kk-l);end;
beta0(:,:,kk)=aux;
end;
end;

%TTQr=r primeras filas de TQ


TTQr(:,1:m)=beta00*diag(q);
for j=1:s-1;TTQr(:,m*j+1:(j+1)*m)=beta0(:,:,j)*diag(q);end;

control_state.TTQr = TTQr;
control_state.h_k = zeros(r,p*r+p*m);
control_state.u_k = zeros(1,r);

%tengo que tener tanto cada salida y como cada entrada u dados como
%vectores columna, es decir y de mxN, u de r*N, N=cantidad de
%observaciones
end

G.3.2. lfd control.m

function [ control_state ] = lfd_control(control_state, y, u)


% example:
% [A, B] = arx_ljung(y, u, 2);
% u_next_step = lfd_control(y, u, 2, 0.99999, 1/625000, ones (1,2*4), A, B)

y = y;
u = u;

%y de m*N datos de las salidas


%u de r*N datos de entradas, N=cantidad de observaciones
%p=orden del modelo ARX

m = control_state.m;
r = control_state.r;
p = control_state.p;
s = control_state.s;
limits = control_state.limits;
alpha = control_state.alpha;
mu = control_state.mu;
TTQr = control_state.TTQr;
h_k_1 = control_state.h_k;
k = size(y,2)+1;

if m ~= size(y,1)
error(lfd_control:input,Coordinates from state vector y do not match m previously defined. y
(coords= %d), m= %d, size(y,1), m);

Apendice G. Codigos Fuente de Avances Experimentales 232


Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

end
if r ~= size(u,1)
error(lfd_control:input,Coordinates from actuation vector u do not match r previously
defined. u(coords= %d), r= %d, size(u,1), m);
end
if size(y,2) ~= size(u,2)
error(lfd_control:input,Unable to determine current time step number: k. Samples in y(count: %d) and
u(count: %d) do not match, size(y,2), size(u,2));
end

%k indica el paso a partir del cual se aplica el control; debe ser k-p-s >=1,
%k-s>=1
if k-p-s < 1
error(lfd_control:k_validation, Arguments error. TimeStep, Order and PredictionHorizon should match
the following rule: k-p-s>=1. k: %d,p: %d,s: %d., k, p, s);
end

%According to Kegerise:
%3. Update the data vectors ys(k-s) and vp(k-p-s).
%4. Update h(k) according to Eq. 16. so h(kk + 1) = alpha*h(kk)-2mu*TTQr*ys(kk-s)*vp(kk-p-s)
%5. Compute the control effort as: u(k) = hvp(k-p).

%ys_k_1_s = ys(k-1-s) = [y(k-1-s);y(k-1-s+1);...;y(k-2)]


ys_k_1_s = reshape(y(:,(k-1-s):(k-2)), m*s, 1);
%vp_k_1_p_s = vp(k-1-p-s) = [u(k-1-p-s);...;u(k-2-s);y(k-1-p-s);...;y(k-2-s)]
up_k_1_p_s = reshape(u(:,(k-1-p-s):(k-2-s)), r*p, 1);
yp_k_1_p_s = reshape(y(:,(k-1-p-s):(k-2-s)), m*p, 1);
vp_k_1_p_s = [up_k_1_p_s;yp_k_1_p_s];

%vp_k_p = vp(k-p) = [u(k-p);...;u(k-1);y(k-p);...;y(k-1)]


up_k_p = reshape(u(:,(k-p):(k-1)), r*p, 1);
yp_k_p = reshape(y(:,(k-p):(k-1)), m*p, 1);
vp_k_p = [up_k_p;yp_k_p];

%according to eq. 16 h(k) = alpha*h(k-1) - 2*mu*tqr*ys(k-1-s)*vp(k-1-p-s)


h_k = alpha * h_k_1 - 2 * mu * TTQr * ys_k_1_s * vp_k_1_p_s;
u_k = h_k * vp_k_p;

indices_out_of_limit = find(u_k < limits.min_value);


u_k(indices_out_of_limit) = limits.min_value;
indices_out_of_limit = find(u_k > limits.max_value);
u_k(indices_out_of_limit) = limits.max_value;
u_k = u_k;

control_state.u_k = u_k;
control_state.h_k = h_k;

end

Apendice G. Codigos Fuente de Avances Experimentales 233


Bibliografa

[1] Neculai Andrei. Modern control theory - a historical perspective, 2005.

[2] Frederic Archambeau, Namane Mechitoua, and Marc Sakiz. Code saturne: a finite volume
code for the computation of turbulent incompressible flows. International Journal on Finite
Volumes, 1, 2004.

[3] G. Artana, A. Cammilleri, J. Carlier, and E. Memin. Strong and weak constraint variational
assimilations for reduced order modelling for flow control. Physics of fluids, 8:32643288,
2012.

[4] G. Artana, R. Sosa, E. Moreau, and G. Touchard. Control of the near wake-flow around a
circular cylinder with electrohydrodynamic actuators. Experiments in Fluids, 35:580588,
2003.

[5] Alexandre Barbagallo, Denis Sipp, and Peter J. Schmid. Closed-loop control of an open
cavity flow using reduced-order models. Journal of Fluid Mechanics, 641:150, 12 2009.

[6] J. F. Beaudoin, O. Cadot, J. L. Aider, and J. E. Wesfreid. Drag reduction of a bluff body
using adaptive control methods. Physics of Fluids, 18(085107), 2006.

[7] Thomas R. Bewley. Flow control: new challenges for a new renaissance. Progress in Aeros-
pace Sciences, 37(1):21 58, 2001.

[8] F.A. Brauer and C. Castillo-Chavez. Mathematical Models in Population Biology and Epi-
demiology. Texts in Applied Mathematics. Springer-Verlag, 2001.

[9] O. Cadot, B. Thiria, and J.F. Beaudoin. Passive drag control of a turbulent wake by local
disturbances. Solid Mechanics and its Applications, 14:529537, 2009.

[10] A. Cammilleri, F. Gueniat, J. Carlier, L. Pastur, E. Memin, F. Lusseyran, and G. Artana.


Pod-spectral decomposition for fluid flow analysis and model reduction. Theoretical and
Computational Fluid Dynamics, pages 129, 2013.

[11] Louis N. Cattafesta, Qi Song, David R. Williams, Clarence W. Rowley, and Farrukh S.
Alvi. Active control of flow-induced cavity oscillations. Progress in Aerospace Sciences,
44(7-8):479502, 2008.

[12] CEI. EnSight User Manual for Version 10.0. Computational Engineering International,
Inc, 1 2012.

[13] H. Choi, W. Jeon, and J. Kim. Control of flow over a bluff body. Annual Review of Fluid
Mechanics, 40(1):113139, 2008.

[14] D W Clarke, C Mohtadi, and P S Tuffs. Generalized predictive control - part 1. the basic
algorithm. Automatica, 23(2):137148, March 1987.

234
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

[15] D W Clarke, C Mohtadi, and P S Tuffs. Generalized predictive control - part 2. extensions
and interpretations. Automatica, 23(2):149160, March 1987.

[16] Kelly Cohen, Selin Aradag, Stefan Siegel, Jurgen Seidel, and Tom McLaughlin. A Metho-
dology Based on Experimental Investigation of a DBD-Plasma Actuated Cylinder Wake for
Flow Control, chapter 6, pages 117138. InTech Europe, 2012.

[17] S. Scott Collis, Ronald D. Joslin, Avi Seifert, and Vassilis Theofilis. Issues in active flow con-
trol: Theory, control, simulation, and experiment. Progress in Aerospace Sciences, 40(1):237
289, 2004.

[18] Juan DAdamo, Leo M. Gonzalez, Alejandro Gronskis, and Guillermo Artana. The scenario
of two-dimensional instabilities of the cylinder wake under electrohydrodynamic forcing: a
linear stability analysis. Fluid Dynamics Research, 44(055501):20, 2012.

[19] E. Detemple-Laake and H. Eckelmann. Phenomenology of karman vortex streets in oscilla-


tory flow. Experiments in Fluids, 7(4):217227, 1989.

[20] T. Duriez, J.L. Aider, and J.E. Wesfreid. Self-sustaining process through streak generation
in a flat-plate boundary layer. Physical Review Letters, 103(14), 2009.

[21] E. Fernandez-Cara and E. Zuazua. Control theory: History, mathematical achievements


and perspectives. Bol. Soc. Esp. Mat. Apl., 26:79140, 2003.

[22] HeinrichE. Fiedler. Control of free turbulent shear flows. In Mohamed Gad-el Hak and
Andrew Pollard, editors, Flow Control, volume 53 of Lecture Notes in Physics, pages 335
429. Springer Berlin Heidelberg, 1998.

[23] Power Generation Fluid Dynamics and Environment Department Single Phase Thermal-
Hydraulics Group. Code Saturne 2.3.1 Theory Guide. EDF R&D, 12 2011.

[24] B. Friedland. Control System Design: An Introduction To State-Space Methods. Dover


Books on Electrical Engineering Series. Dover Publications, Incorporated, 2005.

[25] E. Gillies. Low-dimensional control of the circular cylinder wake. Journal of Fluid Mecha-
nics, 371:157178, 1998.

[26] E. A. Gillies. Low-dimensional control of the circular cylinder wake. Journal of Fluid
Mechanics, 371:157178, 9 1998.

[27] G. Godard and M. Stanislas. Control of a decelerating boundary layer. part 3: Optimization
of round jets vortex generators. Aerospace Science and Technology, 10(6):455464, 2006.

[28] A. Gronskis, R. Sosa, and G. Artana. Modelling ehd actuation with a slip velocity. 2009.

[29] H.R. Hall. Governors and governing mechanism. The Technical Publishing Co., 287, Deans-
gate, Manchester, 1903.

[30] Aurelien Herve, Denis Sipp, Peter J. Schmid, and Manuel Samuelides. A physics-based
approach to flow control using system identification. Journal of Fluid Mechanics, 702:26
58, 2012.

[31] Shao-Ching Huang and John Kim. Control and system identification of a separated flow.
Physics of Fluids, 20(101509), 2008.

Bibliografa 235
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

[32] X.Y. Huang. Feedback control of vortex shedding from a circular cylinder. Experiments in
Fluids, 20(3):218224, 1996.

[33] Jer-Nan Juang and Minh Phan. Deadbit predictive controllers. Technical Memorandum
112862, Nasa, 1997.

[34] T. Jukes and K. Choi. Control of unsteady flow separation over a circular cylinder using
dielectric-barrier-discharge surface plasma. Physics of fluids, 21(9):094106, 2009.

[35] Michael A. Kegerise, Randolph H. Cabell, and Louis N. Cattafesta. Real time feedback
control of flow-induced cavity tones - part 1: Fixed-gain control. Journal of Sound and
Vibration, 307:906923, 2007.

[36] Michael A. Kegerise, Randolph H. Cambell, and Louis N. Cattafesta. Real time feedback
control of flow-induced cavity tones - part 2: Adaptive control. Journal of Sound and
Vibration, 307:924940, 2007.

[37] David B. Kirk and Wen-mei W. Hwu. Programming Massively Parallel Processors: A
Hands-on Approach. Morgan Kaufmann Publishers Inc., San Francisco, CA, USA, 1st
edition, 2010.

[38] J. Kostas, J.M. Foucaut, and M. Stanislas. The flow structure produced by pulsed-jet vortex
generators in a turbulent boundary layer in an adverse pressure gradient. Flow, Turbulence
and Combustion, 78(3-4):331363, 2007.

[39] Petros Koumoutsakos. Active control of vortexwall interactions. Physics of Fluids,


9(12):38083816, 1997.

[40] Alexey Kozlov. Plasma actuators for bluff body flow control. PhD thesis, University of
Notre Dame, 2010.

[41] J.C. Lin. Review of research on low-profile vortex generators to control boundary-layer
separation. Progress in Aerospace Sciences, 38(4-5):389420, 2002.

[42] Lennart Ljung. System Identification: Theory for the User. Prentice-Hall Inc., Englewood
Cliffs, N.J., 1987.

[43] D. J. Mavriplis. Unstructured grid techniques. Annual Review of Fluid Mechanics,


29(1):473514, 1997.

[44] D.Q. Mayne, J.B. Rawlings, C.V. Rao, and P.O.M. Scokaert. Constrained model predictive
control: Stability and optimality. Automatica, 36(6):789 814, 2000.

[45] M.L. Minsky and Massachusetts Institute of Technology. Artificial Intelligence Laboratory.
Matter, Mind and Models. AI memo. Massachusetts Institute of Technology, Project MAC,
1965.

[46] M. Munska and T. Mclaughlin. Circular cylinder flow control using plasma actuators. AIAA
paper 2005-0141, 2005.

[47] Katsuhiko Ogata. Modern Control Engineering. Prentice Hall PTR, Upper Saddle River,
NJ, USA, 4th edition, 2001.

[48] A.V. Oppenheim, R.W. Schafer, and J.R. Buck. Discrete-time signal processing. Prentice-
Hall signal processing series. Prentice Hall, 1999.

Bibliografa 236
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

[49] A.V. Oppenheim, A.S. Willsky, and S.H. Nawab. Signals and Systems. Prentice-Hall signal
processing series. Prentice-Hall International, 1997.
[50] A. E. Perry, M. S. Chong, and T. T. Lim. The vortex-shedding process behind two-
dimensional bluff bodies. Journal of Fluid Mechanics, 116:7790, 2 1982.
[51] S.Joe Qin and Thomas A. Badgwell. A survey of industrial model predictive control tech-
nology. Control Engineering Practice, 11(7):733 764, 2003.
[52] J. Reece Roth. Prospective industrial applications of the one atmosphere uniform glow
discharge plasma. 1:223 Vol.1, 2004.
[53] J. Richalet and D. ODonovan. Predictive Functional Control: Principles and Industrial
Applications. Advances in industrial control. Springer London, Limited, 2009.
[54] A. Roshko. On the wake and drag of bluff bodies. J. Aeronaut. Sci., 22:124132, 1955.
[55] Anatol Roshko. Experiments on the flow past a circular cylinder at very high reynolds
number. Journal of Fluid Mechanics, 10:345356, 5 1961.
[56] J. Reece Roth, Daniel M. Sherman, and Stephen P. Wilkinson. Electrohydrodynamic flow
control with a glow-discharge surface plasma. AIAA Journal, 38(7):11661172, 2000.
[57] K. Roussopoulos. Feedback control of vortex shedding at low reynolds number. Journal of
Fluid Mechanics, 248:267296, 1993.
[58] C. Rowley. Model reduction for fluid flows using balanced proper orthogonal decomposition.
Int. J. Bifurc. Chaos, 15:9971013, 2005.
[59] H. Schlichting. Boundary-Layer Theory. MacGraw-Hill, 7th edition, 1979.
[60] D. Shiels and A. Leonard. Investigation of a drag reduction on a circular cylinder in rotary
oscillation. Journal of Fluid Mechanics, 431:297322, 3 2001.
[61] C.A. Smith and A.B. Corripio. Principles and practice of automatic process control. Wiley,
2006.
[62] Roberto Sosa. Mecanismos de Acople en Actuadores EHD. PhD thesis, Facultad de Inge-
niera, Universidad de Buenos Aires, 2007.
[63] R.B. Stull. An Introduction to Boundary Layer Meteorology. Atmospheric and oceanograp-
hic sciences library. Kluwer Academic Publishers, 1988.
[64] G. Tadmor, O. Lehmann, B.R. Noack, L. Cordier, J. Delville, J. Bonnet, and M. Morzynski.
Reduced-order models for closed-loop wake control. Philos Trans A Math Phys Eng Sci,
369(1940):151324, 2011.
[65] Gilead Tadmor, Oliver Lehmann, Bernd R. Noack, and Marek Morzynski. Mean field
representation of the natural and actuated cylinder wake. Physics of Fluids, 22(3):034102,
2010.
[66] B. Thiria, S. Goujon-Durand, and J.E. Wesfreid. The wake of a cylinder performing rotary
oscillations. Journal of Fluid Mechanics, 560:123147, 2006.
[67] Lloyd Nicholas Trefethen. Finite difference and spectral methods for ordinary and partial
differential equations. Cornell University - Department of Computer Science and Center for
Applied Mathematics, 1996.

Bibliografa 237
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca

[68] N. Wiener. Cybernetics: Or, Control and Communication in the Animal and the Machine.
The @MIT paperback series: Massachusetts Institute of Technology. Mit Press, 1965.

[69] C H K Williamson. Vortex dynamics in the cylinder wake. Annual Review of Fluid Mecha-
nics, 28(1):477539, 1996.

[70] M. M. Zdravkovich. Flow Around Circular Cylinders: Volume I: Fundamentals. Flow


Around Circular Cylinders: A Comprehensive Guide Through Flow Phenomena, Experi-
ments, Applications, Mathematical Models, and Computer Simulations. OUP Oxford, 1997.

[71] M. M. Zhang, L. Cheng, and Y. Zhou. Closed-loop-controlled vortex shedding and vibra-
tion of a flexibly supported square cylinder under different schemes. Physics of Fluids,
16(5):14391448, 2004.

[72] K. Zhou and J.C. Doyle. Essentials of Robust Control. Prentice-Hall International editions.
Prentice-Hall International, 1998.

Bibliografa 238

Вам также может понравиться