Traducción del original en coreano escrito por el autor. Leer el original (한국어)
[Reseña de artículo] Cómo una DQN domó los vórtices de un perfil con un chorro sintético — Control activo de flujo por aprendizaje por refuerzo
La subida de sustentación del artículo, de 1.79 a cerca de 2.0, mueve la recompensa solo 0.042 junto a un desplazamiento de 3. El casillero de 12 m/s no es ese objetivo.
Con un ángulo de ataque alto, los vórtices se desprenden del perfil por turnos. La sustentación oscila en cada ciclo y el ala tiembla. Lo habitual es cambiar la forma o congelar un forzamiento periódico (periodic forcing). Hammouda y colaboradores (2026) no fijaron la velocidad del chorro. Un chorro sintético (un actuador de masa neta nula que sopla y luego aspira) queda cerca del borde de ataque, y una DQN elige una de 21 velocidades entre 0 y 20 m/s.
Con el deslizador de ε cerca de 0, las barras se clavan en la velocidad que primero salió alta. En 0.2 la exploración amarilla se adelgaza y la explotación cian se junta cerca de 12 m/s.
Al pulsar Train conviene mirar si las elecciones amarillas menguan mientras cambia la altura de las barras. Al subir ε a 0.8, el agente sigue probando otras velocidades aunque ya conozca un casillero bueno.
Dónde se sitúa el artículo#
- Título: Application of deep reinforcement learning for aerodynamic control around an angled airfoil via synthetic jet
- Autores: N. Ghezaiel Hammouda, R. Khan, L. Mostafa y otros (Scientific Reports, 2026)
- Marco: flujo laminar débilmente compresible con número de Reynolds (inercia sobre viscosidad) 100 y Mach 0.2. Un perfil a alto ángulo con un chorro sintético cerca del borde de ataque.
- Resultado: Dueling DQN convergió con más estabilidad, redujo el desprendimiento de vórtices, subió la sustentación y bajó el arrastre.
Con Re 100 el flujo es laminar. Un ángulo alto igual suelta vórtices detrás del ala. Ese desprendimiento es lo que mueve la sustentación y el arrastre.
Traducir los vórtices a un problema de aprendizaje por refuerzo#
El aprendizaje por refuerzo (una política que crece por ensayo para aumentar una recompensa) arranca cuando quedan nombradas tres cosas.
- Estado (state): presión y velocidad que leen sensores virtuales alrededor del perfil y en la estela. El artículo anota un aprendizaje más rápido cuando la velocidad se suma a la presión.
- Acción (action): velocidad del chorro . Enteros de 0 a 20 m/s con paso de 1 m/s, 21 casilleros, porque la DQN pide un conjunto discreto.
- Recompensa (reward): una línea que recorta el arrastre y sube la sustentación.
y son el arrastre y la sustentación promediados en una ventana de acción. y mantienen la recompensa positiva y fijan el peso de la sustentación frente al arrastre. El artículo usó , . Una acción es un período de desprendimiento. El entrenamiento recorre 300 episodios de 25 períodos cada uno.
ε-greedy: entre exploración y explotación#
El agente guarda el valor de la acción en . La actualización es el paso de Bellman.
es la tasa de aprendizaje, descuenta la recompensa futura y es el mejor valor esperado desde el estado siguiente.
Queda cómo probar una acción cuyo valor todavía se desconoce. ε-greedy elige la mejor hasta ahora (explotación) con probabilidad y un casillero al azar (exploración) con probabilidad . Un grande deambula. Uno pequeño se sienta pronto. Esa probabilidad explica por qué las barras de arriba se atascan cerca de 0 y caminan hacia 12 m/s cerca de 0.2.
El chorro sintético como acción#
Un chorro sintético hace vibrar una membrana, sopla por un orificio y vuelve a aspirar. La masa neta es cero. El impulso sí entra en la capa límite. El tamaño adimensional de ese empuje es el coeficiente de cantidad de movimiento.
, , son la densidad, la velocidad y el diámetro del orificio del chorro. , , son la densidad y la velocidad de la corriente libre y la cuerda. El orificio está en el lado de succión, cerca del borde de ataque, en , con diámetro de 0.2 mm. El impulso extra retrasa la separación (boundary layer separation) y debilita el desprendimiento.
A Mach 0.2 las ondas acústicas aprietan el paso de tiempo antes de que el agente vea la estela. Cómo integrar ese problema de bajo Mach sin borrar las ondas es el tema de un esquema IMEX asintóticamente preservante. La figura de la estela queda después de la recompensa impresa.
Manos a la obra: encender el chorro con Q-learning#
La red del artículo no se traslada entera. Una tabla de valores Q conserva la amplitud en casilleros y las velocidades discretas. El estado es un casillero de la amplitud de oscilación de la sustentación. La acción es la velocidad del chorro.
import numpy as np
class SyntheticJetEnv:
"""Entorno fenomenológico 1D de perfil-estela.
Estado : amplitud de oscilacion de sustentacion discretizada (0..n_bins-1)
Accion : nivel de velocidad del chorro {0,1,...,20} m/s
Recompensa : R1 - <Cd> + R2*<Cl> (Ec. 4 del articulo)
"""
def __init__(self, n_bins=6, peak=12, R1=3.0, R2=0.2, seed=0):
self.n_bins, self.peak = n_bins, peak
self.R1, self.R2 = R1, R2
self.rng = np.random.default_rng(seed)
self.amp = 1.0 # amplitud de desprendimiento normalizada (1 = sin control)
def reset(self):
self.amp = 1.0
return self._bin()
def _bin(self):
return min(self.n_bins - 1, int(self.amp * self.n_bins))
def step(self, action):
ctrl = action / 20.0 # autoridad de control 0..1
target = max(0.05, 1.0 - 0.8 * ctrl) # el chorro reduce la amplitud
self.amp += 0.5 * (target - self.amp) # relajacion de primer orden
cl = 1.8 + 0.2 * ctrl - 0.4 * self.amp # coeficiente de sustentacion
cd = 0.085 - 0.006 * ctrl + 0.02 * self.amp # coeficiente de resistencia
waste = 0.01 * max(0, action - self.peak) # penalizacion por soplar de mas
reward = self.R1 - cd + self.R2 * cl - waste
reward += self.rng.normal(0, 0.05)
return self._bin(), reward
def epsilon_greedy(q_row, eps, rng):
if rng.random() < eps:
return int(rng.integers(len(q_row))) # explorar
return int(np.argmax(q_row)) # explotar
def train_jet_controller(episodes=300, steps=25, alpha=0.1, gamma=0.9, eps0=0.3):
env = SyntheticJetEnv()
n_actions = 21
Q = np.zeros((env.n_bins, n_actions))
rng = np.random.default_rng(1)
history = []
for ep in range(episodes):
s = env.reset()
eps = eps0 * (1 - ep / episodes) # decaimiento lineal
total = 0.0
for _ in range(steps):
a = epsilon_greedy(Q[s], eps, rng)
s2, r = env.step(a)
Q[s, a] += alpha * (r + gamma * Q[s2].max() - Q[s, a])
s, total = s2, total + r
history.append(total / steps)
best = int(np.argmax(Q.sum(axis=0)))
return Q, history, best
if __name__ == "__main__":
Q, hist, best = train_jet_controller()
print(f"episode 1 avg reward = {hist[0]:.3f}")
print(f"episode 300 avg reward = {hist[-1]:.3f}")
print(f"learned jet velocity = {best} m/s")La salida es esta.
episode 1 avg reward = 3.12
episode 300 avg reward = 3.25
learned jet velocity = 12 m/sCon el deslizador de velocidad del chorro en 0, los vórtices se desprenden por turnos y la oscilación de es ancha. Al llevarlo a 15–20 m/s los vórtices se atenúan y la estela se aquieta. Los 12 m/s impresos no son el extremo derecho de ese deslizador. Al pausar y dejar el deslizador cerca de 12 se compara si la estela quieta que busca la recompensa es el mismo casillero donde se detuvo la tabla.
El 3.25 es el equilibrio. En la acción 12 la fracción es 0.6 y la amplitud queda en . La sustentación es y el arrastre es . La recompensa coincide con el episodio 300. El desperdicio aparece al pasar de la acción 12: 12 m/s es el último casillero limpio, no la cima de la sustentación.
A 20 m/s la amplitud es 0.2, la sustentación 1.92, el arrastre 0.083 y el desperdicio baja la recompensa a 3.22. Con el chorro apagado la recompensa queda en 3.18. La ganancia aprendida es 0.07. El 3.12 es ruido, no esa base.
La sustentación del artículo sube de 1.79 a cerca de 2.0. Por la recompensa se mueve solo 0.042 junto a . A 12 m/s la sustentación del juguete es 1.71 y a 20 m/s llega a 1.92. La velocidad impresa marca dónde empieza la penalización, no el objetivo de sustentación.
Los hermanos de la DQN: Double frente a Dueling#
El artículo puso tres variantes de DQN en paralelo.
- DQN clásica: el se inclina a sobreestimar el valor.
- Double DQN: una red elige la acción y otra la valora, lo que recorta esa sobreestimación.
- Dueling DQN: parte en un valor de estado y una ventaja .
es lo bueno que es el estado. es cuánto esta acción supera el promedio dentro de él. Cuando 11 m/s y 13 m/s se parecen, el valor de estado se aprende una vez. Por eso la curva Dueling del artículo fue la que menos se movió.
Cinco capas de 128 neuronas se asentaron dentro de 300 episodios. Con el control activo, subió de 1.79 a cerca de 2.0 y la estela se calmó. Es un número distinto de la sustentación 1.71 que la tabla produce a 12 m/s.
Por qué 12 m/s no es un óptimo de sustentación#
Los 0.13 ganados en 300 episodios son un desplazamiento pequeño al lado de . La subida de sustentación del artículo aporta 0.042 a la recompensa. Si esa brecha basta para fiarse de un casillero de 1 m/s es otra decisión.
Distinguir 11 m/s de 13 m/s en un CFD real obliga a integrar 25 períodos de desprendimiento por episodio. Un esquema que estira el paso y aun así pierde la estabilidad es el tema de la factura de un paso 1001 veces mayor. ¿Esa factura separa la penalización de desperdicio a 12 m/s de la sustentación 2.0 del artículo?
Relacionados
Comparte si te resultó útil.