SuperNotes by yuri.rodrix

Notas de Yuri.Rodrix


Página tipo blog en el que voy a publicar mis notas de aprendizaje, en especial de temas como matemáticas, física y quizá algo de programación

Redes neuronales
Redes neuronales
Redes neuronales
Redes neuronales
Redes neuronales
Redes neuronales

Simulación FDTD de Antenas

Este post abre la caja negra del simulador de antenas del playground: qué cálculo corre por debajo y qué física enseña cada antena. El método es FDTD (diferencias finitas en el dominio del tiempo): se resuelven las ecuaciones de Maxwell tal cual, paso a paso en el tiempo, sobre una malla, en la GPU mediante WebGPU. Nada de fórmulas cerradas — la onda simplemente evoluciona.

El punto de partida: Maxwell en forma de rotacional

FDTD discretiza las dos ecuaciones de Maxwell con derivada temporal — la ley de Faraday y la ley de Ampère-Maxwell— en su forma diferencial. En unidades normalizadas (ε=μ=1\varepsilon=\mu=1, Δx=1\Delta x=1, c=1c=1) quedan:

Ht=1μ×E\frac{\partial \mathbf{H}}{\partial t} = -\frac{1}{\mu}\,\nabla\times\mathbf{E}Et=1ε×H\frac{\partial \mathbf{E}}{\partial t} = \frac{1}{\varepsilon}\,\nabla\times\mathbf{H}

Cada ecuación vectorial son tres escalares. Por ejemplo, la componente xx del campo eléctrico depende solo de cómo varían HzH_z y HyH_y en el espacio:

Ext=1ε(HzyHyz)\frac{\partial E_x}{\partial t} = \frac{1}{\varepsilon}\left(\frac{\partial H_z}{\partial y} - \frac{\partial H_y}{\partial z}\right)

La clave conceptual: un campo cambia en el tiempo porque el otro varía en el espacio. Un H\mathbf{H} que se curva alimenta a E\mathbf{E}, y viceversa. Esa realimentación cruzada es la onda electromagnética propagándose.

La malla de Yee: dónde vive cada campo

El truco que hace estable y preciso a FDTD (Kane Yee, 1966) es no guardar todos los campos en el mismo punto. Cada componente se almacena desfasada media celda de modo que cada derivada espacial caiga, de forma natural, justo en el punto donde se necesita. Las componentes de E\mathbf{E} viven en las aristas del cubo:

Exi+12,j,k,Eyi,j+12,k,Ezi,j,k+12E_x\big|_{i+\frac12,\,j,\,k},\quad E_y\big|_{i,\,j+\frac12,\,k},\quad E_z\big|_{i,\,j,\,k+\frac12}

y las de H\mathbf{H} en los centros de las caras:

Hxi,j+12,k+12,Hyi+12,j,k+12,Hzi+12,j+12,kH_x\big|_{i,\,j+\frac12,\,k+\frac12},\quad H_y\big|_{i+\frac12,\,j,\,k+\frac12},\quad H_z\big|_{i+\frac12,\,j+\frac12,\,k}

Además del desfase espacial, hay un desfase temporal: E\mathbf{E} se evalúa en pasos enteros nn y H\mathbf{H} en pasos medios n+12n+\tfrac12. Es el esquema leapfrog (rana saltarina): E y H se van pisando el turno indefinidamente.

El grueso del cálculo: la actualización leapfrog

Toda la simulación es repetir dos kernels que reemplazan las derivadas continuas por diferencias entre celdas vecinas (δ\delta denota esa diferencia discreta). Definiendo el número de Courant cn=cΔtΔxc_n = \frac{c\,\Delta t}{\Delta x}, el paso de actualización de E\mathbf{E} es:

Exn+1=Exn+cnεr(δyHzδzHy)E_x^{\,n+1} = E_x^{\,n} + \frac{c_n}{\varepsilon_r}\left(\delta_y H_z - \delta_z H_y\right)

y el de H\mathbf{H}, medio paso después:

Hxn+12=Hxn12cn(δyEzδzEy)H_x^{\,n+\frac12} = H_x^{\,n-\frac12} - c_n\left(\delta_y E_z - \delta_z E_y\right)

Escrito con índices explícitos, el update de ExE_x sobre su arista (i+12,j,k)(i+\tfrac12,j,k) es literalmente lo que corre la GPU por celda:

Exn+1i+12,j,k=Exn+cnεr[(Hzi,j,kHzi,j1,k)(Hyi,j,kHyi,j,k1)]E_x^{\,n+1}\big|_{i+\frac12,j,k} = E_x^{\,n} + \frac{c_n}{\varepsilon_r}\Big[\big(H_z|_{i,j,k}-H_z|_{i,j-1,k}\big)-\big(H_y|_{i,j,k}-H_y|_{i,j,k-1}\big)\Big]

El factor 1/εr1/\varepsilon_r es cómo entran los dieléctricos: dentro de un material con εr>1\varepsilon_r>1 el campo crece más lento, y la onda viaja más despacio → refracción y reflexión parcial emergen solas. Sin material, εr=1\varepsilon_r=1 y el término desaparece.

No hay matriz que invertir ni sistema que resolver: cada celda se actualiza leyendo solo a sus vecinas inmediatas. Por eso FDTD es masivamente paralelo y encaja perfecto en un compute shader — millones de celdas, una invocación por celda, dos despachos por paso de tiempo.

Estabilidad: la condición CFL

El esquema explícito solo es estable si la información no avanza más de una celda por paso. En 3D la condición de Courant–Friedrichs–Lewy es:

cn=cΔtΔx    130.577c_n = \frac{c\,\Delta t}{\Delta x} \;\le\; \frac{1}{\sqrt{3}} \approx 0.577

Si cnc_n supera 1/31/\sqrt3 la simulación explota (los campos divergen a infinito en pocos pasos). El simulador usa cn=0.5c_n=0.5, cómodamente por debajo del límite. Una consecuencia útil: la longitud de onda medida en celdas es

λ=cnf[celdas]\lambda = \frac{c_n}{f}\quad[\text{celdas}]

Esta misma relación es la que fija el largo del cable de la fuente que dibuja el simulador: lo pinta de λ/2\lambda/2, la referencia de un elemento resonante de media onda. Sube la frecuencia y el cable se acorta solo — antena más pequeña.

Fuentes: cómo se inyecta la energía

La antena se excita en una brecha de alimentación (delta-gap): una sola arista de la malla a la que cada paso se le suma una forma de onda. Hay tres:

Senoidal

s(t)=Asin(ωt+ϕ),ω=2πfs(t) = A\sin(\omega t + \phi),\qquad \omega = 2\pi f

Onda continua a una frecuencia fija. Para ver el régimen permanente y patrones a una ff.

Pulso gaussiano

s(t)=Aexp ⁣[12(tt0σ)2]s(t) = A\,\exp\!\left[-\tfrac12\left(\frac{t-t_0}{\sigma}\right)^2\right]

Banda ancha en un disparo: excita todas las frecuencias a la vez (barridos de impedancia / S₁₁).

Gaussiana modulada

s(t)=Aexp ⁣[12(tt0σ)2]sin(ωt+ϕ)s(t) = A\,\exp\!\left[-\tfrac12\left(\frac{t-t_0}{\sigma}\right)^2\right]\sin(\omega t + \phi)

Pulso centrado en ff: banda ancha pero acotada alrededor de la resonancia.

Y dos maneras de aplicarla — la fuente blanda suma (deja pasar la onda reflejada), la dura fija el valor (la refleja como un conductor):

soft: E+=s(t)hard: E=s(t)\text{soft: } E \mathrel{+}= s(t)\qquad\text{hard: } E = s(t)

El vector de corriente cian del simulador es justamente s(t)s(t) dibujado en vivo sobre el eje del cable: late y cambia de signo al ritmo de la fuente, en sincronía con los frentes de onda que salen.

Fronteras absorbentes (CPML)

La malla es finita pero el espacio libre no. Sin tratamiento, la onda rebota en las paredes y contamina todo. La solución es una CPML (Convolutional Perfectly Matched Layer): una capa de unas 12 celdas en cada cara donde se añade una conductividad artificial graduada que absorbe la onda sin reflejarla, fingiendo un espacio infinito. Se implementa con campos auxiliares ψ\psi que siguen una recursión; fuera de la capa los coeficientes son neutros y el kernel colapsa al Yee clásico, así que el mismo shader sirve con y sin frontera.

De campo cercano a patrón de radiación (NFFT)

El simulador resuelve el campo cerca de la antena, pero el patrón de radiación vive en el infinito. El puente es la transformada near-to-far: por el principio de equivalencia, los campos sobre una caja cerrada de Huygens que rodea la antena se reemplazan por corrientes equivalentes

Js=n^×H,Ms=n^×E\mathbf{J}_s = \hat{n}\times\mathbf{H},\qquad \mathbf{M}_s = -\,\hat{n}\times\mathbf{E}

Se acumula su transformada (una DFT a la frecuencia de la fuente, integrada sobre las seis caras) en los potenciales de radiación

N=SJsejkr^rdS,L=SMsejkr^rdS\mathbf{N}=\oint_S \mathbf{J}_s\,e^{\,jk\,\hat{r}\cdot\mathbf{r}'}\,dS',\qquad \mathbf{L}=\oint_S \mathbf{M}_s\,e^{\,jk\,\hat{r}\cdot\mathbf{r}'}\,dS'

y se proyectan a las componentes esféricas del campo lejano, con η\eta la impedancia del vacío:

Eθ(Lϕ+ηNθ),Eϕ(LθηNϕ)E_\theta \propto -\left(L_\phi + \eta\,N_\theta\right),\qquad E_\phi \propto \left(L_\theta - \eta\,N_\phi\right)

De ahí salen el diagrama polar, la directividad, la relación frente-espalda y el ancho de haz que muestra el panel de diagnósticos — el globo de radiación sobre la simulación es exactamente Elejano(θ,ϕ)|E_\text{lejano}|(\theta,\phi).

Las antenas: un mecanismo físico por cada una

La progresión de presets no es aleatoria: cada antena introduce una razón distinta por la que un patrón deja de ser omnidireccional. Esa es la columna vertebral pedagógica.

Dipolo de media onda

Lλ2L \approx \frac{\lambda}{2}

El control: un hilo de λ/2\lambda/2 con corriente senoidal forma el patrón rosquilla clásico. Es lo que se ve cuando nada rompe la simetría.

Monopolo sobre plano de tierra

El método de imágenes: el plano PEC refleja y crea un dipolo virtual. Media rosquilla hacia arriba, cancelación abajo — contraste directo con el dipolo libre.

Yagi-Uda

Elementos parásitos. Un reflector y varios directores sin alimentar reradian con la fase justa; la interferencia entre ellos concentra el haz hacia adelante. Ganancia y F/B reales medibles.

Parche microstrip

frc2Lεr,eff,εr,effεr+12f_r \approx \frac{c}{2L\sqrt{\varepsilon_{r,\text{eff}}}},\qquad \varepsilon_{r,\text{eff}}\approx\frac{\varepsilon_r+1}{2}

Radiación de apertura. Las dos ranuras en los bordes del parche radian en fase → haz broadside (perpendicular a la placa). El sustrato εr\varepsilon_r acorta la resonancia.

Slot (principio de Babinet)

ZslotZdipolo=η24Z_{\text{slot}}\,Z_{\text{dipolo}} = \frac{\eta^2}{4}

Dualidad E↔H. Una ranura en un plano es el complemento del dipolo: mismo patrón, polarización girada 90°. La dualidad de Maxwell hecha visible.

Array en fase (phased array)

θ0=arcsin ⁣(Δϕkd)  =d=λ/2  arcsin ⁣(Δϕπ)\theta_0 = \arcsin\!\left(-\frac{\Delta\phi}{k\,d}\right)\;\overset{d=\lambda/2}{=}\;\arcsin\!\left(-\frac{\Delta\phi}{\pi}\right)

Interferencia controlada. N fuentes coherentes con desfase progresivo Δϕ\Delta\phi dirigen el lóbulo sin mover nada — el haz se barre con un slider.

Vivaldi (ranura cónica)

Onda viajera. Ni resonancia ni interferencia entre fuentes: la onda viaja por una ranura que se ensancha exponencialmente y radia endfire a lo largo del camino, cada banda desde una sección distinta → comportamiento ultra banda-ancha.

Por qué WebGPU

FDTD es vergonzosamente paralelo y su cuello de botella es el ancho de banda de memoria, no la lógica. Una malla de 1283128^3 son más de dos millones de celdas, cada una con seis campos, actualizadas decenas de veces por segundo. En la CPU sería un crawl; en la GPU vía compute shaders (WGSL) corre en tiempo real con el render volumétrico encima, en el mismo dispositivo, sin copiar datos de vuelta. La métrica canónica del panel de rendimiento — celdas/segundo— mide justo eso.