Академический Документы
Профессиональный Документы
Культура Документы
Facultad de Ingeniera
TESIS DE GRADO
Presentada por:
Pablo Daniel Roca
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.1 Introduccion 12
2.6 Conclusiones 35
3.1 Introduccion 37
3.6 Conclusiones 58
4 Ensayo Experimental 59
4.1 Introduccion 60
Apendices 112
E Publicaciones 127
E.1 Anales de la AFA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
E.2 Physics of Fluids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
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.
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
11
2.1 Introduccion
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:
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.
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).
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
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.
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.
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.
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.
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)
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].
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).
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
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:
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 [...]
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
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
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.
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
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:
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.
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)
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.
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.
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.
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.
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
34
2.6 Conclusiones
35
Parte 3
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.
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.
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.
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
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).
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].
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.
45
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
Figura 3.3.3: Evolucion del numero de Strouhal en funcion del numero de Reynolds (Williamson, 1996) [69].
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.
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.
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.
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
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 )
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.
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
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
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 .
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
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.
K = (T T QT + Isr )1 T T Q (3.5.5)
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
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:
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
58
Parte 4
Ensayo Experimental
59
4.1 Introduccion
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].
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
cada region al generar la malla en el Apendice B.1. Se incluye ademas la distribucion final de
celdas de acuerdo a su tamano.
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.
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
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
...
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)
iProbe = iProbe + 1
xyzcap(1,iProbe) = xProbe
xyzcap(2,iProbe) = yProbe
xyzcap(3,iProbe) = 0.00d0
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
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
do iphas = 1, nphas
itypfb(ifac,iphas) = isymet
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
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
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
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
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.
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.
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.
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
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.
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.
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).
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).
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
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;
}
}
...
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.
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.
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
[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
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.
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.
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.
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.
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.
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.
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
T_column(1:m,:)=beta00;
for j=2:s;
T_column((j-1)*m+1:j*m,:)=beta0(:,:,j-1);
end;
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
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;
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;
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
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.
Tabla 4.6.1: Valores definidos para los distintos parametros de control del sistema.
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.
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.
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.).
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.).
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.
u(t) = u + u0 (t)
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
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.
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].
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
113
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca
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.
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).
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.
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.
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.
Cabe destacar que el nivel de ajuste se mantiene similar en todos los casos.
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.
Figura D.3: Tamano en la separacion del nuevo mallado para las lneas de la geometra.
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.
Tabla D.1: Valores definidos para los distintos parametros de control del sistema.
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.
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:
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:
127
Sistema de Control de Flujos a Lazo Cerrado Pablo D. Roca
(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
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).
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)
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.
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.
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.
We consider a two-dimensional flow around a circular cylinder and the control objective of stabilizing the wake
(suppression of the vortex shedding).
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).
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.
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
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.
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).
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),
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,
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:
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
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:
12
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
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
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.
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.
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.
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.
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
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
(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
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
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,
% 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
% 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);
%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);
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
end
F.2.2. chrComputeAverage.m
F.2.3. chrComputeVorticityAverageForGeoXY.m
[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;
F.2.4. chrExtractBinaryHeader.m
F.2.5. chrFindFiles.m
F.2.6. chrFindFilesAndComputeAverage.m
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);
F.2.7. chrGetAmountOfHeadingCharacters.m
F.2.8. chrReadBinaryContent.m
headerCharacters = chrGetAmountOfHeadingCharacters();
fseek(file, headerCharacters, -1);
F.2.9. chrReadBinaryGeo.m
F.2.10. chrReadVelocity2D.m
F.2.11. chrWriteBinaryContent.m
F.2.12. chrWriteCaseFile.m
fclose(file);
end
F.2.13. geoComputeIntersectionArea.m
F.2.14. geoGetBoundingRectsForDelta.m
end
end
end
F.2.15. geoTransformContentToNonXY.m
F.2.16. geoTransformContentToXY.m
end
end
end
F.2.17. geoTransformMeshToXYGrid.m
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
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;
F.2.18. polygonArea.m
F.2.19. polygonClip.m
%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]]);
end %computeIntersection
if ( crossVector(3) <= 0 )
in = true;
else
in = false;
end
end %inside
% % Sutherland-Hodgman Algorithm
clippedPolygon = subjectPolygon;
numVerticies = size(clipPolygon,1);
clipVertexPrevious = clipPolygon(end,:);
inputList = clippedPolygon;
clippedPolygon = [];
previousVertex = inputList(end,:);
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,:);
elseif( inside(previousVertex,clipBoundary) )
subjectLineSegment = [previousVertex;inputList(subjectVertex,:)];
clippedPolygon(end+1,1:2) = computeIntersection(clipBoundary,subjectLineSegment);
end
previousVertex = inputList(subjectVertex,:);
clipVertexPrevious = clipPolygon(clipVertex,:);
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;
cacheFolder = /media/Datos/Pablo/Workspace/tmp/cache/0.045;
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);
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;
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);
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
F.3.4. computeReynoldsTensor.m
F.3.5. computeRMS.m
F.3.6. selectIntegrationCoordinates.m
!-------------------------------------------------------------------------------
! 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:
! -------
! 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
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.
!-------------------------------------------------------------------------------
! 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 &
!================
( 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
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
! --- 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
! 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
! 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,
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
iphas = 1
irovar(iphas) = 0
ivivar(iphas) = 0
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
! 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.
iutile = 0
if (iutile.eq.1) then
endif
return
end subroutine
!===============================================================================
TYPE probes_line
double precision xStart
double precision yStart
double precision xEnd
double precision yEnd
double precision separation
END TYPE
TYPE(probes_line) probesLines(0)
TYPE(probes_area) probesAreas(2)
!===============================================================================
! 1. Input-output (entsor.h)
!===============================================================================
! --- write auxiliary restart file iecaux = 1 yes, 0 no
iecaux = 1
! 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
iProbe = iProbe + 1
xyzcap(1,iProbe) = xProbe
xyzcap(2,iProbe) = yProbe
xyzcap(3,iProbe) = 0.00d0
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)
iProbe = iProbe + 1
xyzcap(1,iProbe) = xProbe
xyzcap(2,iProbe) = yProbe
xyzcap(3,iProbe) = 0.00d0
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),
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.
! Note that the default condition for scalars (other than k and epsilon)
! is homogeneous Neumann.
! Remarks
! =======
! 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.
! * For other values: take as an approximation the value in the adjacent cell
! i.e. as above with iel = ifabor(ifac).
!-------------------------------------------------------------------------------
! 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, *) ! ! ! !
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
! Local variables
integer idebia, idebra
!===============================================================================
! 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)
actuatorValuesInitialized = .true.
endif
idebia = idbia0
idebra = idbra0
d2s3 = 2.d0/3.d0
!===============================================================================
! 2. Assign boundary conditions to boundary faces here
!$PhysicalNames
!1 Layer0
!2 entrada
!3 salida
!4 pared
!5 simetria
!6 interna
!7 actuador
!5 simetria
!$EndPhysicalNames
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
do iphas = 1, nphas
itypfb(ifac,iphas) = iparoi
enddo
enddo
do iphas = 1, nphas
itypfb(ifac,iphas) = isymet
enddo
enddo
if (ntcabs.ge.actuatorStartingStep) then
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
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
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)=
% =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
[m,N] = size(y);
[r,N] = size(u);
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);
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;
y = pvget(data, OutputData);
y = y{1};
ny = size(y , 2);
s = RandStream.create(mrg32k3a,NumStreams,1);
RandStream.setDefaultStream(s); %to ensure deterministic output
%randseed(45233); %to ensure deterministic output
s = RandStream.create(mrg32k3a,NumStreams,1);
RandStream.setDefaultStream(s); %to ensure deterministic output
%randseed(45233); %to ensure deterministic output
act(delayBeforeRampSteps+rampUpSteps+1:delayBeforeRampSteps+rampUpSteps+rampDownSteps) =
peakMagnitude*[1-deltaRampDown:-deltaRampDown:0];
act = repmat(act, 1, 2);
end
/*
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"
std::stringstream prefixConverter;
prefixConverter << "[CPU." << argv[1] << "]";
prefixConverter >> logPrefix;
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);
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(){
}
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));
}
}
}
}
}
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 );
}
#endif
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
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
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 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();
#endif
F.6.7. Controller.cpp
#include <sstream>
#include <set>
#include "Controller.h"
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;
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());
logger << "Received y data values. Rows: " << yMatrix.getRows() << ". Cols: " << yMatrix.getColumns() <<
std::endl;
cummulativeOutputs = yMatrix;
cummulativeOutputsForModel = yMatrix;
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();
}
}
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());
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;");
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);
F.6.8. Logger.h
#ifndef LOGGER__
#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;
}
};
#endif
%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
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
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_column(1:m,:)=beta00;
for j=2:s;
T_column((j-1)*m+1:j*m,:)=beta0(:,:,j-1);
end;
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
% 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
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;
control_state.u_k = u_k;
end
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() {
if (!(ep = engOpen("\0"))) {
logger << "Closing engine..." << std::endl;
engClose(ep);
}
}
logger << "Putting matrix. Variable: " << matrixVariableName << std::endl;
engPutVariable(ep, matrixVariableName.c_str(), matrix);
mxDestroyArray(matrix);
F.6.13. Matrix.h
#ifndef MATRIX__
#define MATRIX__
class Row {
private:
std::vector< Cell > data;
public:
Row(size_t columns) {
this->data.resize(columns);
}
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;
}
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"
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) {
Cell value;
converter >> value;
probeValues[i] = value;
}
}
}
probes.seekg(0, std::ios::beg);
std::ifstream::pos_type posBegin = probes.tellg();
probes.seekg(-1, std::ios::end);
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.";
}
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;
}
}
F.6.16. SaturneCommunicator.h
#ifndef SATURNE_COMMUNICATOR__
#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"
std::string strValue;
converter >> strValue;
logger << "Sending " << strValue << "." << std::endl;
actuatorFile << strValue <<std::endl;
}
#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 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
CAMERA_TYPE *configInMem;
pxd.FreeFG (hFG);
return 0;
}
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;
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.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"
{
std::ifstream file(filepath.c_str());
if (file)
file >> target;
else
throw Exception("The file could not be opened for reading");
}
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)
{
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"
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
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]
*/
//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
}
}
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));
}
return this->estimatedA.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
[m,N] = size(y);
[r,N] = size(u);
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);
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
}
}
return newShape;
}
free(aCula);
free(tauCula);
return resultTransposed.transpose();
}
//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);
//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
//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);
//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.");
gsl_matrix_free(matrixCopy);
gsl_permutation_free(p);
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> 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()
{
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;
}
}
}
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());
}
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());
}
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);
}
/**
* 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;
}
};
return input;
}
#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;
G.2.7. common/Exception.h
#ifndef EXCEPTION_H_
#define EXCEPTION_H_
#include <string>
#include <exception>
#endif /* EXCEPTION_H_ */
G.2.8. common/Exception.cpp
#include "Exception.h"
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
k = size(y,2);
%m=cantidad de componentes de y
%r=cantidad de componentes de u
m = size(y,1);
r = size(u,1);
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
%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;
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
y = y;
u = u;
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);
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).
control_state.u_k = u_k;
control_state.h_k = h_k;
end
[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.
[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.
[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.
[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.
[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.
[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.
[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.
[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