Bitácora del proyecto

Qué hice, qué aprendí y por qué importa, contado para que lo entienda cualquiera. Proyecto final de Ondas gravitacionales e investigación asistida por IA (UBA, 2026).

Esta página es un diario de trabajo. No hace falta saber física para leerla: cada vez que aparece una palabra técnica, está explicada ahí mismo o en el glosario del final. Quien quiera las ecuaciones las encuentra en las páginas técnicas, enlazadas en cada sección.

1. La pregunta del proyecto, en palabras simples

Las ondas gravitacionales son arrugas en el propio espacio que viajan a la velocidad de la luz. Las producen fenómenos muy violentos, como el choque de dos agujeros negros, y desde 2015 se detectan con instrumentos como LIGO. Algunas de esas ondas podrían venir de los primeros instantes del universo, y traer información de una época de la que no nos llega ninguna luz.

Una de esas épocas es el recalentamiento (en inglés, preheating). Según la idea más aceptada, el universo recién nacido pasó por una inflación: una expansión muy rápida impulsada por un campo llamado inflatón. Cuando la inflación terminó, el inflatón quedó oscilando, y en esas oscilaciones le fue pasando su energía a todas las demás partículas. Esa transferencia fue violenta y desordenada, y un proceso así produce ondas gravitacionales.

Pensá en una hamaca. Si la empujás en el momento justo de cada vaivén, cada empujón suma y la hamaca sube cada vez más: eso es una resonancia. El inflatón oscilando hace lo mismo con los otros campos: les da "empujones" en el momento justo y los hace crecer muy rápido. Esa energía que crece de golpe y de forma desordenada es la que agita el espacio y produce las ondas.

Casi todos los estudios de este proceso suponen que el inflatón sólo le pasa energía a campos "simples" (los campos escalares, que en cada punto tienen un solo número). Pero el inflatón también podría estar conectado con campos de gauge, que son los que transmiten fuerzas: el campo electromagnético es el ejemplo más conocido. Un campo de gauge se comporta distinto: tiene dirección, forma líneas de campo y puede armar tubos de flujo.

La pregunta del proyecto es: si al recalentamiento se le agrega un campo de gauge, ¿cuánto cambia la "huella" de ondas gravitacionales que deja? Esa huella es el espectro: cuánta onda hay en cada frecuencia. Cambiar el campo de gauge podría mover el pico del espectro, cambiar su altura o dejar marcas propias que un modelo sin campos de gauge no tiene.

2. La herramienta: simular el universo en una caja

Este proceso es demasiado complicado para resolverlo con lápiz y papel: todo interactúa con todo al mismo tiempo. Lo que se hace es simularlo en una computadora. Se toma un cubo de espacio, se lo divide en una grilla de puntos (una red o lattice) y en cada punto se guarda cuánto vale cada campo. Después se avanza en el tiempo de a pasitos, aplicando las leyes de la física en cada punto.

Es como una foto digital: la imagen real es continua, pero la cámara la guarda como una grilla de píxeles. Con suficientes píxeles, la foto se parece mucho a la realidad. Acá los píxeles son puntos del espacio, y en vez de colores guardan los valores de los campos.

El programa que uso se llama CosmoLattice. Es público, y lo escribió un grupo de físicos que se especializa en esto. Su gran ventaja es que simula campos de gauge respetando exactamente sus reglas, no de forma aproximada. Trae tres modelos armados que sirven justo para la comparación del proyecto:

ModeloQué tienePara qué lo uso
lphi4El inflatón y otro campo escalar. Sin campos de gauge.El control: la versión "sin" contra la que comparar.
lphi4U1El inflatón con carga, conectado a un campo de gauge parecido al electromagnético.El caso con un campo de gauge.
lphi4SU2U1El inflatón conectado a dos campos de gauge, parecidos a los de la fuerza electrodébil.Un caso de gauge más rico, si el tiempo alcanza.

qué ecuaciones resuelve CosmoLattice y cómo pone los campos de gauge en la red está en ¿Qué es CosmoLattice?.

3. Lo que hice hasta ahora

Antes de correr la primera simulación "de verdad" (sección 3.1), primero me aseguré de entender exactamente qué hace el programa, porque si no, cualquier resultado que saliera podría estar mal interpretado. Fue en este orden:

  1. Instalé CosmoLattice y compilé los tres modelos. Corrí una prueba chiquita (una caja de 16×16×16 puntos, durante muy poco tiempo) sólo para confirmar que el programa funciona. Esa prueba no dice nada de física.
  2. Junté la bibliografía: 13 artículos científicos, entre los que explican el programa y los que estudiaron antes ondas gravitacionales con campos de gauge. Están en bibliografía/, con una nota de para qué sirve cada uno.
  3. Escribí una introducción al programa, ¿Qué es CosmoLattice?.
  4. Estudié en detalle cómo el programa convierte la física en números y lo escribí en Bases teóricas de los modelos gauge.
  5. Verifiqué cada cuenta. Escribí un programa, verificar_variables_de_programa.py, que rehace las cuentas del artículo y las compara con lo que hace el código de CosmoLattice. Hoy hace 21 comprobaciones y todas dan bien. Así, si mañana alguien cambia algo, se puede volver a correr y ver si sigue todo en orden.
  6. Anoté de dónde sale cada número. Cada número o afirmación del proyecto queda registrado en provenance/, con qué programa lo calculó y qué decisiones hubo que tomar. La idea es que cualquiera pueda rastrearlo sin tener que preguntarme.

3.1. La primera simulación: el piloto del control (23 de septiembre de 2026)

Corrí el modelo de control, lphi4, con los parámetros acordados pero en una caja más chica (128 puntos por lado en lugar de 256), para probar que todo funciona antes de gastar tiempo en la corrida grande. Tardó 1 hora y 17 minutos en esta computadora (usando sus 8 núcleos) y la energía se conservó muy bien (el error nunca pasó de 2 en 10 000). Los parámetros están en code/lphi4_piloto_N128.in y las salidas en data/lphi4_piloto_N128/.

Para mirar los resultados armé un cuaderno interactivo, code/analisis_corridas.py (se abre con marimo edit code/analisis_corridas.py). Muestra cómo se expande el universo, cómo oscila el inflatón, en qué escalas crece el campo hijo y cuándo aparecen las ondas gravitacionales. Lo que se ve:

Comparación con lo publicado. Dufaux y colaboradores (2007) simularon este mismo modelo. Al traducir las diferencias (usaron un λ nueve veces menor), nuestro resultado coincide con el de ellos en la altura del pico (3,8×10⁻¹¹ contra ∼3×10⁻¹¹), en su frecuencia (a 20 %), en la forma de la cola de frecuencias bajas y en los momentos en que pasa cada cosa. La única diferencia está en las escalas más chicas: nuestra caja no llega a resolverlas, y ahí el espectro sigue creciendo al final. Para eso hace falta la caja de 256 puntos.

El análisis completo, con todas las figuras, está en El piloto del control.

Cuánto van a tardar los modelos con gauge. Hice pruebas cortas de los tres modelos con la caja de 128 puntos (data/pruebas_costo_N128/). El control tarda unos 80 minutos. El de U(1), unas 8 horas y media. El de SU(2)×U(1), unos 3 días y medio: sus campos son matrices y cada paso cuesta diez veces más. Los tres entran en la memoria, de a uno por vez. Además apareció una restricción del programa: con campos de gauge y ondas gravitacionales no se puede usar el integrador del piloto (LF) y hay que usar otro (VV2). Por eso conviene repetir el control con VV2, para que los tres usen el mismo. La ley de Gauss se cumple desde el primer instante, con un error de una parte en cien mil millones.

3.2. El control con el otro integrador: ¿cambia algo? (23 de septiembre de 2026)

Un integrador es la receta que usa el programa para avanzar el universo de un instante al siguiente. El piloto usó uno llamado LF (leapfrog, "salto de rana"), que calcula los campos y sus velocidades en instantes alternados, medio paso corridos. Los modelos con gauge no pueden usarlo junto con las ondas gravitacionales. La fuente de las ondas necesita el campo eléctrico y el magnético en el mismo instante, y LF los tiene medio paso corridos. Por eso los modelos con gauge van a usar VV2 (velocity Verlet), que sí los sincroniza.

Para que la comparación entre modelos sea justa, los tres tienen que usar el mismo integrador. Así que repetí el control con VV2: mismos parámetros, misma semilla (el mismo "ruido" inicial exacto), solo cambia el integrador. Entrada: code/lphi4_control_N128_VV2.in, salidas en data/lphi4_control_N128_VV2/ y figuras en figures/lphi4_control_N128_VV2/ (hechas con el mismo cuaderno). Tardó 1 hora y 32 minutos (el piloto, 1 hora y 17) y usó la misma memoria, 318 MB.

qué se midepiloto (LF)control (VV2)diferencia
amplitud real del inflatón, A1,1381,138ninguna
velocidad de crecimiento del campo hijo, μ0,20020,20010,02 %
velocidad de crecimiento de las ondas0,7570,757ninguna
los gradientes llegan al 1 % (τ)83,983,9ninguna
50 % / 90 % de las ondas hechas (τ)130 / 203130 / 201< 1 %
energía final en ondas, ρ_GW/ρ9,87×10⁻⁶9,92×10⁻⁶0,4 %
pico del espectro hoy, h²Ω (g★ = 100)6,8×10⁻¹¹ a 1,1×10⁸ Hz6,9×10⁻¹¹ a 1,1×10⁸ Hz2 % en altura, nada en frecuencia
pico de (Ω_gw)_p en x ≈ 1502,83×10⁻⁶2,70×10⁻⁶5 %
crecimiento del pico entre x ≈ 170 y el final22 %28 %6 puntos
error máximo de la energía (Friedmann)2,1×10⁻⁴7,7×10⁻⁴ver abajo

Lo que se ve:

Conclusión: el cambio de integrador no afecta los resultados. El control con VV2 pasa a ser la referencia con la que se van a comparar los modelos con gauge, que usan el mismo integrador. El piloto con LF queda como la validación contra Dufaux: da lo mismo.

3.3. ¿Se puede usar una caja con menos puntos? (24 de septiembre de 2026)

Los modelos con gauge son caros: con 128 puntos por lado, U(1) tarda unas 8 horas y media y SU(2)×U(1) unos 3 días y medio. El costo crece como N³, así que con 64 puntos por lado serían 8 veces menos. Antes de hacerlo hay que saber cuánto cambian los resultados. Lo probé con el control, que es barato: repetí la corrida de la sección 3.2 cambiando solo N (32, 48, 64 y 96), con la misma caja y la misma semilla. Además hice otra con 64 puntos y la caja a la mitad de tamaño (kIR = 0,5). Así los puntos quedan igual de juntos que con 128 y la red resuelve las mismas longitudes de onda cortas. Entradas en code/lphi4_N*_VV2.in, salidas en data/convergencia_N/, figuras en figures/convergencia_N/, y el script de la comparación es code/convergencia_N.py.

corridalongitud de onda más corta que resuelve (k máximo)energía final en ondas / la de N = 128altura del máximo del espectro / la de N = 128tiempo
N = 327×6,0×191,2 min
N = 4810,5×2,5×8,54,5 min
N = 6413,8×1,75×5,110,5 min
N = 9620,8×1,21×2,037,5 min
N = 128 (referencia)27,81192 min
N = 64, caja a la mitad27,5×1,003×1,0210,8 min
N = 128, caja a la mitad55,5×0,84×0,9879 min

Lo que se ve:

Conclusión: achicar la caja sirve para abaratar las corridas; bajar la resolución con la misma caja, no.

¿Y N = 128, está convergido? Para saberlo corrí también 128 puntos con la caja a la mitad (k máximo ≈ 55, el doble que la referencia; 79 minutos). La respuesta es que no del todo:

Eso explica por qué N = 64 con la caja a la mitad coincidía tan bien con N = 128: las dos llegan al mismo k máximo y tienen el mismo error en el borde. Para comparar modelos, la parte confiable del espectro es el pico y lo que está a su izquierda (k ≲ 4). La meseta a la derecha del pico depende de la resolución.

¿La caja a la mitad alcanza para los campos de gauge? Revisé en qué longitudes de onda resuena cada modelo (code/analisis_parametros.py::banda_principal, con la amplitud real del inflatón A = 1,138). En las unidades del control:

Con eso se decidió (24 de septiembre de 2026) correr U(1) con 64 puntos y la caja a la mitad: code/lphi4U1_N64_kIR0.5_VV2.in.

3.4. El primer modelo con gauge, U(1), y un problema con cómo arranca (24 de septiembre de 2026)

La primera corrida de U(1) (64 puntos, caja a la mitad, 1 hora y 16 minutos) salió numéricamente bien: la ley de Gauss se cumplió todo el tiempo con un error menor a una parte en mil millones. Pero la resonancia del campo gauge llegó mucho más tarde que la del campo hijo en el control: al 1 % de la energía en τ ≈ 105 en lugar de 68.

La causa es cómo arranca el campo gauge en CosmoLattice. Un campo gauge, como el electromagnético, tiene dos partes. La parte longitudinal la fijan las cargas, a través de la ley de Gauss. La parte transversal son las ondas, como la luz. Es la que resuena con el inflatón y la que produce ondas gravitacionales. CosmoLattice arranca el campo gauge solo con la parte longitudinal, y la transversal en cero exacto (así lo dicen el código, u1initializer.h, y el paper del código, arXiv:2102.01031, ecs. 97–102). La parte transversal solo se enciende después, alimentada por combinaciones de segundo orden de las fluctuaciones del inflatón, que son muchísimo más chicas. El campo hijo del control, en cambio, arranca con sus fluctuaciones cuánticas de vacío. La comparación no estaba en igualdad de condiciones.

Lo que hice: le agregué a CosmoLattice una condición inicial nueva, ICtype_U1 = RandomWithMatterTransverseVacuum. Hace lo mismo que la original (el inflatón arranca con el mismo ruido exacto y la parte longitudinal se fija con la ley de Gauss) y además le da a la parte transversal sus fluctuaciones de vacío, con el mismo criterio que usa el programa para el campo hijo. El cambio está en code/parches/u1_vacio_transversal.patch, explicado en code/parches/LEEME.md. Lo probé antes de usarlo: la ley de Gauss sigue en una parte en cien mil millones, el ruido del inflatón es idéntico, y la energía que se agrega es la de dos polarizaciones con la energía de vacío del campo hijo.

Midiendo bien el crecimiento. Para ver qué crece hay que mirar el campo magnético, que es puramente transversal. El eléctrico mezcla la parte longitudinal, que no resuena. Mirando el eléctrico me pareció que la resonancia gauge "se frenaba" a mitad de camino. Era un error de lectura: en las dos corridas los modos transversales crecen al ritmo que predice la teoría (Floquet con q = 120: μ ≈ 0,20–0,23 en k de 0,5 a 2), igual que el campo hijo. Lo único que cambia es desde qué tamaño arrancan.

qué se mide (unidades del control)control (campo hijo χ)U(1), como arranca CosmoLatticeU(1), con vacío transversal
el campo hijo/gauge llega al 1 % de la energía (τ)6810568
... al 10 % (τ)8914886
fracción máxima de la energía49 %40 %41 %
energía final en ondas, ρ_GW/ρ9,9×10⁻⁶7,1×10⁻⁶ (−29 %)1,5×10⁻⁵ (+53 %)
espectro de ondas en k de 0,5 a 2,5 (parte confiable), respecto del control10,3 veces0,6–0,7 veces
espectro de ondas en k de 3 a 4, respecto del control10,4–0,5 veces0,85–1,1 veces

Lo que se ve:

Cuidado: esto es con una sola semilla y en la red chica. Faltan otras semillas para saber cuánto varía el espectro por puro azar (entre dos integradores, sección 3.2, la fase turbulenta variaba 2–5 %). Actualización del 27 de septiembre: con tres semillas el cociente es 0,56–0,79 (medio 0,68); ver sección 3.6.

Datos en data/lphi4U1_N64_kIR0.5_VV2/ y data/lphi4U1_vacioT_N64_kIR0.5_VV2/. Figuras en figures/comparacion_modelos/ (hechas con code/comparar_modelos.py) y el crecimiento por modo en figures/lphi4U1_*/mu_por_modo_vs_control.png (con code/crecimiento_por_modo_U1.py).

3.5. SU(2) arranca igual, y al arreglarlo apareció un "fotón" (27 de septiembre de 2026)

Antes de largar la corrida larga de SU(2)×U(1) (~11 horas) revisé cómo arranca el campo SU(2). Tiene el mismo problema que tenía U(1) (sección 3.4): CosmoLattice lo arranca con el campo en cero exacto y solo la parte longitudinal que fija la ley de Gauss (su2initializer.h). La parte transversal, la que resuena y produce ondas gravitacionales, arranca en cero. Así que hacía falta un cambio parecido al de U(1).

Cómo lo armé. Agregué la opción ICtype_SU2 = RandomWithMatterTransverseVacuum (code/parches/su2_vacio_transversal.patch, explicado en code/parches/LEEME.md). Para eso tuve que averiguar cómo guarda el programa el campo SU(2). No guarda el campo directamente: guarda "links", unas matrices que conectan puntos vecinos de la red. Leyendo cómo calcula la energía y cómo avanza en el tiempo, el campo B entra como g·dx·B/2 en el link y el campo eléctrico se guarda dividido por 2. Hubo un detalle más: el programa elige los números al azar a partir del nombre de cada campo auxiliar. Si usaba un solo auxiliar para todo, los tres "colores" de SU(2) (y el U(1)) habrían recibido exactamente el mismo ruido.

La primera versión estaba mal, y la prueba lo mostró. Hice dos corridas cortas con la misma semilla, una con el arranque de CosmoLattice y otra con el vacío nuevo, y verifiqué:

Pero al dejar evolucionar un rato, el vacío no se quedaba quieto como debería: la energía iba y venía entre la parte eléctrica y la magnética, y la magnética del U(1) llegó a multiplicarse por 3,6. Eso pasa cuando a un campo se le da el vacío de una masa que no es la que realmente tiene.

La causa: los dos campos gauge se mezclan. En este modelo, el inflatón tiene carga de los dos campos a la vez (U(1) y SU(2)). Eso hace que una combinación del campo U(1) con uno de los colores de SU(2) se comporte como un campo aparte, con su propia masa. Es lo mismo que pasa en el Modelo Estándar de partículas, donde de la mezcla salen el fotón y la partícula Z. Con nuestros parámetros (q_A = q_B = 60) quedan cuatro campos independientes:

campoqué combinación esmasa² (unidades del programa)equivale a
"fotón"U(1) + color 1, a medias0no resuena
"Z"U(1) − color 1, a medias240q = 120, como el campo hijo del control
dos "W"colores 2 y 3120q = 60

Mi primera versión le daba masa 120 al U(1) y a cada color por separado, sin ver la mezcla. La versión final no escribe las masas a mano: al arrancar, el programa las calcula con las mismas operaciones que usa para mover los campos, verifica que la cuenta sea consistente, separa los cuatro campos independientes y le da a cada uno su vacío con su masa. El resultado fue justo la tabla de arriba.

cuánto cambia la parte agregada en el primer instante (t de 0 a 0,7)energía eléctricaenergía magnética
referencia: U(1) solo (lphi4U1, ya validado)1,00–1,180,87–1,00
primera versión, sin mezcla: U(1)0,73–1,401,0–3,6
versión final: U(1)1,00–1,160,87–1,00
versión final: SU(2)1,00–1,170,86–1,00

Con la mezcla bien tratada, los dos campos se comportan como la referencia.

Dos cosas a tener en cuenta para el análisis:

Lo que esto dice del modelo: en SU(2)×U(1) no son "dos campos gauge con q = 60 cada uno". Hay uno que resuena como el campo hijo del control (la Z), dos que resuenan más débil (las W) y uno que no resuena (el fotón). Va a ser importante para interpretar las ondas gravitacionales.

Datos de las pruebas en data/prueba_su2_vacioT/ (con su LEEME.md), verificación con code/validar_vacio_su2.py. La corrida larga usa code/lphi4SU2U1_vacioT_N64_kIR0.5_VV2.in y guarda en data/lphi4SU2U1_vacioT_N64_kIR0.5_VV2/.

3.6. ¿Es azar? U(1) contra el control con tres semillas (27 de septiembre de 2026)

La "semilla" es el número con el que el programa elige el ruido inicial (las fluctuaciones cuánticas). Cambiarla es como repetir el experimento con otra tirada de dados: la física es la misma, pero los detalles cambian. En la sección 3.4 el espectro de ondas de U(1) salió 0,6–0,7 veces el del control, pero con una sola semilla. Corrí dos semillas más (2345 y 3456) de los dos modelos, con todo lo demás igual.

semillaresonancia al 1 % (τ), control / U(1)espectro U(1) / control en k = 0,5–2,5energía total en ondas, U(1) / control
123468,3 / 68,10,61–0,69 (medio 0,66)1,53
234568,4 / 68,10,47–0,89 (medio 0,67)1,65
345668,4 / 68,10,56–0,85 (medio 0,72)1,64
con los promedios de las tres0,56–0,79 (medio 0,68)

Lo que se ve:

Datos en data/semillas/ (con su LEEME.md), análisis con code/semillas_U1.py, figura en figures/semillas/U1_vs_control_semillas.png.

3.7. SU(2)×U(1): los resultados (28 de septiembre de 2026)

La corrida larga arrancó a las 23:18 del 27 y terminó bien a las 08:40 del 28 (9 horas y 22 minutos con los 8 núcleos, 249 MB de memoria). La calidad numérica fue buena: la ley de Gauss de SU(2) tuvo un error máximo de una parte en un millón (y al final una en cien mil millones), la de U(1) una en mil millones, y la ecuación de Friedmann (la cuenta de energía del universo) cerró con un error máximo de 0,04 %. Es una sola semilla (1234), la misma que las primeras del control y de U(1).

Cómo separé los campos. El programa guarda la energía de U(1) y la de SU(2) (los tres colores juntos), no la de cada campo de la tabla de la sección 3.5. Pero se pueden despejar: como el fotón y la Z son mitad U(1) y mitad color 1, la energía de "Z + fotón" es el doble de la del U(1), y la de las dos W es la de SU(2) menos la de U(1). Esto vale salvo un término cruzado entre la Z y el fotón, que medí: es ~0,1 % de la energía del U(1), así que no cambia nada. Solo en τ ≈ 75–110 la resta para las W no es confiable, porque ahí las W todavía son muy chicas comparadas con ese término.

qué se mide (unidades del control)control (χ)U(1) (A)SU(2)×U(1), todos... Z + fotón... las dos W
llega al 1 % de la energía (τ)68,368,168,168,1117
llega al 10 % (τ)88,686,085,785,7130
fracción de la energía al final48 %40 %64 %31 %32 %
ritmo de crecimiento en la fase lineal (μ de la energía, τ 30–70)0,160,160,160,07
ritmo de crecimiento tardío (τ 100–125)0,020,040,030,18

Lo que se ve:

Las ondas gravitacionales (figura figures/lphi4SU2U1_vacioT_N64_kIR0.5_VV2/ondas_gravitacionales.png):

k (unidades del control)0,511,522,5promedio
SU(2)×U(1) / control0,801,061,921,660,641,11
SU(2)×U(1) / U(1)1,281,533,132,390,931,68
U(1) / control (misma semilla)0,630,690,610,690,690,66

Cuidado: es una sola semilla. Las semillas de la sección 3.6 muestran que el espectro por punto varía hasta un tercio de una tirada a otra. Para afirmar el "más ondas cerca del pico" hacen falta más semillas de SU(2)×U(1) (~9 horas cada una).

Datos en data/lphi4SU2U1_vacioT_N64_kIR0.5_VV2/ (con su LEEME.md), análisis con code/analisis_SU2U1.py y code/crecimiento_por_modo_U1.py, figuras en figures/lphi4SU2U1_vacioT_N64_kIR0.5_VV2/.

3.8. Cómo se producen las ondas en cada modelo (28 de septiembre de 2026)

Como no daba el tiempo para más semillas, hice cuatro análisis con las corridas que ya estaban, para entender cómo produce ondas gravitacionales cada modelo y no solo cuántas. Todos usan la semilla 1234 de los tres modelos. El programa guardó el espectro de ondas cada 5 unidades de tiempo, así que se puede seguir cómo se arma. Código en code/produccion_gws.py, figuras en figures/produccion_gws/, números en data/produccion_gws.json.

1. ¿Las ondas de SU(2)×U(1) vienen de las W? Las W se disparan tarde (τ ≈ 110–130, sección 3.7), así que parecían las candidatas naturales para explicar el pico más alto. Para averiguarlo miré qué parte de las ondas finales ya existía antes de ese disparo. Una aclaración para poder hacerlo: en estos modelos el universo se expande como si estuviera lleno de radiación, y las ondas también se diluyen como radiación. Por eso, una vez que la fuente se apaga, la cantidad dΩ_GW/d ln k ya no cambia, y comparar el espectro en dos instantes dice cuánto se produjo en el medio.

qué parte de las ondas finales (k ≤ 4) ya existíacontrolU(1)SU(2)×U(1)
en τ = 100 (antes de que las W crezcan)3 %2 %25 % (33 % en k = 1,5–2)
en τ = 120 (las W recién llegan al 1 %)48 %35 %80 %
instante en que llega a la mitad de las ondas finales (τ)121126112

La respuesta es que no. SU(2)×U(1) produce sus ondas antes, no después. El pico en k = 2 ya está formado en τ ≈ 85–100 (figura espectros_en_el_tiempo.png), y cuando las W llegan al 10 % de la energía ya está el 80 % de las ondas. En τ = 100, SU(2)×U(1) tenía 10 veces las ondas del control y 33 veces las de U(1). Al final esa ventaja se achica a 1,24 y 1,86 veces (en k ≤ 2,5), porque el control y U(1) producen la mayor parte más tarde. El exceso cerca del pico viene del período en que la resonancia de la Z empieza a saturar, no de las W. Qué lo causa exactamente no lo sé. Hay dos candidatos: el fotón, que se empieza a llenar en ese momento (se ve en el término cruzado de la sección 3.7), y las interacciones propias de SU(2). Separarlos requeriría guardar los campos completos.

2. ¿Crecen las ondas como el cuadrado del campo? Las ondas las produce el "estiramiento" del campo (su tensión), que es cuadrático en el campo. Si el campo crece como eμτ, su energía crece como e2μτ y la energía en ondas como e4μτ: el doble de rápido que la del campo, en escala logarítmica. Medí las dos pendientes en la fase lineal (τ = 35–62):

controlU(1)SU(2)×U(1)
μ del campo que resuena0,200,210,21
pendiente de las ondas / pendiente de la energía del campo (se espera 2)1,881,781,76

Se cumple en los tres modelos, con un 10 % de diferencia que es razonable, porque la energía total del campo incluye modos que no resuenan. En la fase lineal los tres producen ondas por el mismo mecanismo. Cuidado: en esa fase el nivel de ondas de los modelos gauge está bastante por encima del control (en τ = 60, 30 veces en U(1) y 1000 en SU(2)×U(1)). Pero ahí pesan también las ondas que siembra el vacío de todos los campos, y los modelos gauge tienen más grados de libertad (el control, uno; SU(2)×U(1), ocho polarizaciones). Por eso no tomo esa diferencia como un resultado.

3. ¿Producen menos ondas porque reciben menos energía? La estimación estándar dice que la energía en ondas es proporcional al cuadrado de la fracción de energía que tiene el campo fuente, por un factor que depende de la escala típica de la fuente, (k de esa escala)⁻². Supuse que esa escala es la misma en los tres modelos. Es solo aproximado: la sección 3.9 muestra que SU(2)×U(1) tiene un pico en k = 2, mientras el control tiene una meseta de k = 2 a 4 y U(1) sube hasta el borde de lo confiable. Dividí las ondas en la parte confiable del espectro por el cuadrado de la fracción media de energía en el campo mientras se producen (τ = 70–150):

respecto del controlondas (k ≤ 2,5)(fracción de energía)²eficiencia
U(1)0,660,700,94
SU(2)×U(1)1,240,941,31

U(1) produce menos ondas casi solo porque el campo gauge recibe menos energía (eficiencia 0,94, es decir, casi igual que el control). No hace falta invocar algo especial de los campos gauge. SU(2)×U(1), en cambio, produce un 30 % más de ondas de lo que su energía explicaría. Coincide con el punto 1: el pico se forma temprano y de forma más eficiente. Es una estimación de orden de magnitud y con una semilla, pero la diferencia entre 0,94 y 1,31 es más grande que la dispersión entre semillas del cociente de U(1) (0,66–0,72 de medio). Como la escala típica de la fuente no es exactamente la misma (ver arriba), estas eficiencias valen como tendencia y no como número preciso: si la escala del control está algo por encima de k = 2, la ventaja de SU(2)×U(1) sería algo menor.

4. El espectro de hoy. Con la misma cuenta que el piloto (sección 3.1: después de la simulación, el universo se expande como radiación hasta hoy, con g★ = 100), el máximo de la parte confiable (k ≤ 4) queda en la siguiente tabla. En el control es una meseta y en U(1) está en el borde de lo confiable (sección 3.9), así que la frecuencia del máximo solo es precisa en SU(2)×U(1).

controlU(1)SU(2)×U(1)
frecuencia hoy6,4×10⁷ Hz1,3×10⁸ Hz6,4×10⁷ Hz
h²Ω_GW hoy6,6×10⁻¹¹6,8×10⁻¹¹1,1×10⁻¹⁰

Una unidad de k corresponde a 3,2×10⁷ Hz hoy en los tres modelos, como debe ser, porque es la misma física. Las diferencias entre modelos son factores 0,7–1,9. Todo queda en la zona de ~10⁸ Hz, muy lejos de las frecuencias de los detectores actuales, que miden de nanohertz a kilohertz. Esto es propio del preheating a la escala de energía de λφ⁴: los campos gauge cambian la forma del espectro, pero no lo acercan a algo observable hoy (figura espectro_hoy.png).

En resumen: en la fase lineal los tres modelos producen ondas de la misma manera. U(1) produce menos solo porque se lleva menos energía. SU(2)×U(1) produce más, y antes, en el período en que la resonancia satura; no por las W tardías. Todo esto es con una semilla por modelo.

3.9. La forma del espectro: la respuesta a la pregunta del proyecto (28 de septiembre de 2026)

La pregunta del proyecto es cuánto de la forma del espectro de ondas se debe al campo gauge: posición y altura del pico, y pendientes a cada lado. Hasta acá había comparado alturas. Medí la forma en las siete corridas que hay: control y U(1) con tres semillas cada uno, y SU(2)×U(1) con una. Ajusté una recta en escala logarítmica (dΩ_GW/d ln k ∝ kⁿ) a cada lado del máximo, solo en la parte confiable (k ≤ 4): del lado de las ondas largas (IR) con k = 0,5–1,5, y del lado de las cortas (UV) con k = 2–4. Código en code/pendientes_espectro.py, figura en figures/pendientes_espectro.png.

parte confiable (k ≤ 4)control (3 semillas)U(1) (3 semillas)SU(2)×U(1) (1 semilla)
formasube y queda en una meseta de k = 2 a 4sube hasta el borde de lo confiablepico en k = 2
pendiente IR (k = 0,5–1,5)1,14 ± 0,340,85 ± 0,171,51
pendiente UV cercana (k = 2–4)0,09 ± 0,120,55 ± 0,12−1,78
altura máxima (dΩ_GW/d ln k)3,9–4,0×10⁻⁶4,1–4,3×10⁻⁶ (en k = 4)6,6×10⁻⁶ (en k = 2)

Lo que se ve:

La respuesta a la pregunta del proyecto, con la red usada (N = 64, parte confiable k ≤ 4):

  1. Altura: en la parte confiable, con U(1) el espectro queda en 0,56–0,79 veces el del control (tres semillas). Con SU(2)×U(1) sube hasta 1,7–1,9 veces cerca de k = 1,5–2 (una semilla).
  2. Forma: U(1) desplaza el máximo hacia las ondas cortas; SU(2)×U(1) convierte la meseta del control en un pico en k = 2 y produce las ondas antes.
  3. Pendiente IR: sin cambios medibles.
  4. Por qué: U(1) produce menos ondas porque el campo gauge se lleva menos energía, no por producirlas de otra manera. SU(2)×U(1) produce más de lo que su energía explica, en el período en que la resonancia de la Z satura (sección 3.8). Las W, que se disparan tarde, no son la causa.
  5. Lo que no se puede decir: nada sobre las ondas cortas (k > 4), que no están convergidas, ni sobre la energía total en ondas, que depende de esa zona.

3.10. Los problemas que tuve en el camino (27 y 28 de septiembre de 2026)

Anoto todo lo que salió mal o me hizo perder tiempo, para no repetirlo.

Problemas de física y de medición

Problemas con la computadora y las herramientas

4. Lo que aprendí

4.1. El programa trabaja en sus propias unidades

En este problema aparecen números enormes y diminutos a la vez. Los campos valen alrededor de \(10^{18}\) (un uno con dieciocho ceros) y los acoplamientos alrededor de \(10^{-14}\). Una computadora pierde precisión con números así. La solución de CosmoLattice es cambiar de unidades: elige una unidad de campo y una de tiempo "cómodas" para el problema, de modo que casi todo quede cerca de 1. Son las variables de programa.

Nadie mide la distancia entre ciudades en milímetros, ni el grosor de un pelo en kilómetros: se elige la unidad que deja números manejables. El programa hace lo mismo, y elige como unidad de tiempo más o menos lo que dura una oscilación del inflatón.
Los números de los archivos de configuración están en esas unidades. Por ejemplo, dt = 0.01 no significa "una centésima de segundo" sino "una centésima de la unidad de tiempo del programa". Para interpretar bien cualquier resultado hay que saber traducir de vuelta a unidades físicas.

4.2. La ley de Gauss: una cuenta que tiene que cerrar siempre

Los campos de gauge tienen una regla que se debe cumplir en cada instante y en cada punto: la ley de Gauss. Dice que las líneas de campo eléctrico sólo pueden nacer o terminar donde hay carga. No es algo que "pase con el tiempo": es una condición que tiene que valer siempre.

Es como la contabilidad de una empresa: el dinero que entra y el que sale tienen que cuadrar. Si los libros arrancan cuadrados y cada operación se anota bien, siguen cuadrados para siempre. Pero si arrancan descuadrados, ninguna operación posterior lo arregla.

Por eso importa tanto cómo arranca la simulación. Verifiqué que CosmoLattice prepara el estado inicial de forma que la ley de Gauss se cumpla exactamente, no casi. Eso vuelve útil a la ley de Gauss como alarma durante la simulación: si en algún momento deja de cumplirse, el problema está en el cálculo, no en el punto de partida.

Cuando un control de calidad falla, a veces el que falla es el control. La primera vez que corrí la comprobación de la ley de Gauss dio "FALLA". Revisé la cuenta a mano y el resultado era cero, como correspondía: la herramienta de álgebra no lograba simplificar la expresión. Arreglé la herramienta, no la física. Antes de creerle a una alarma, conviene mirar qué está midiendo.

4.3. El misterio del factor \(\sqrt2\)

Un campo con carga eléctrica se describe con un número complejo, es decir, con dos números: una "parte real" y una "parte imaginaria". Hay dos maneras habituales de escribirlo, y difieren en un factor \(\sqrt2\) (aproximadamente 1,41). Tenía la sospecha de que el código mezclaba las dos convenciones.

Leí cómo el código calcula la energía de ese campo, cómo lo hace evolucionar y cómo produce las ondas gravitacionales. Las tres partes coinciden: el código es consistente y no hay ningún error. Pero apareció otra cosa, más importante.

Dos recetas dicen "2 tazas de harina", pero una usa tazas de té y la otra tazas de desayuno. El número es el mismo; la cantidad de harina, no.

Eso pasa con los archivos de ejemplo que trae el programa. El control (lphi4) y el modelo con gauge (lphi4U1) escriben el mismo número para el valor inicial del inflatón, pero en cada modelo ese número significa algo distinto. Resultado: el modelo con gauge arranca con 4 veces más energía que el control, y con una "intensidad de resonancia" (el parámetro \(q\)) de 1370 contra 300. Si los hubiera comparado tal cual, habría atribuido al campo de gauge diferencias que en realidad vienen de haber arrancado distinto.

Para que la comparación sea justa hay que cambiar una sola cosa por vez. Calculé qué valores poner en los modelos con gauge para que arranquen exactamente igual que el control, de modo que la única diferencia sea el campo de gauge. Los valores están en la página técnica.

4.4. El caso SU(2): cuatro cuentas que tienen que dar cero

El modelo más completo tiene dos campos de gauge, y el inflatón tiene cuatro componentes en lugar de dos. Al arrancar, a cada componente se le agrega un poco de "ruido" que imita las fluctuaciones cuánticas del vacío. El problema es que ese ruido, si se genera al azar, deja en la caja un poco de carga neta. En una caja cerrada la ley de Gauss no tiene solución con carga neta: las líneas de campo no tienen dónde terminar.

El artículo del programa propone generar el ruido con ciertas reglas que cancelan la carga, y comprobé que el código las sigue. Pero encontré un detalle que no está escrito en ningún lado. La fórmula del artículo le da a cada una de las cuatro componentes su propia frecuencia, mientras que el código usa la misma para las cuatro. Hice la cuenta: con frecuencias distintas, la carga no se cancela. El código hace lo correcto y la fórmula del artículo, tomada al pie de la letra, no lo haría. En estos modelos las frecuencias coinciden, así que no cambia nada, pero sí importaría en otros casos.

El código y el artículo no siempre dicen exactamente lo mismo, y cuando difieren no siempre el que tiene razón es el artículo. Vale la pena comparar los dos.

4.5. Un error del programa que ya estaba corregido

Al revisar cómo el programa controla la ley de Gauss en el caso SU(2), encontré un comentario que explica una corrección hecha el 3 de agosto de 2026. Antes de esa fecha, el control tenía un error de escala. Su indicador, que debería valer 0 cuando la ley se cumple, marcaba alrededor de 0,6 aun cuando se cumplía perfectamente. La versión que instalé ya tiene la corrección.

Si alguna simulación hecha con una versión anterior mostró que la ley de Gauss fallaba en el caso SU(2), probablemente era una falsa alarma del control, no un problema físico. Conviene saber con qué versión exacta del programa se trabaja, y por eso el proyecto la deja anotada.

4.6. Qué parámetros usar para que la comparación sea justa

Antes de correr, revisé qué valores usan los autores de cada artículo y por qué. Después calculé qué pasa con cada opción. El detalle completo está en Parámetros comparables. Lo principal:

"Comparar de igual a igual" no sale solo: hay que decidir qué se mantiene fijo, y calcularlo. Acá significa que el inflatón arranque en el mismo estado, que cada modelo tenga un solo canal que recibe la energía con la misma intensidad, y que la grilla cubra la misma porción física del espacio en los tres.

4.7. Sobre la forma de trabajar

5. Lo que sigue, y lo que falta decidir

El piloto del control ya está corrido y validado contra Dufaux et al. (2007) (sección 3.1 y El piloto del control), y el control definitivo usa el mismo integrador que los modelos con gauge (sección 3.2). Con 256 puntos por lado los modelos con gauge no entran en la memoria de esta computadora. La prueba de la sección 3.3 mostró que 64 puntos con la caja a la mitad dan las mismas ondas que 128 puntos, 8 veces más rápido. Ninguna de las dos resuelve bien las longitudes de onda cortas (k > 4 o 5), así que la comparación entre modelos se apoya en el pico y en las longitudes de onda largas.

Entrega (28 de septiembre de 2026). El curso pidió el repositorio completo y un PDF breve (5 páginas como máximo) con texto y figuras. Quedaron dos informes: informe-definitivo.pdf (el pedido, 5 páginas, escrito aparte desde informe-definitivo.html) e informe-extendido.pdf (la página completa del proyecto). Los dos se generan con code/generar_pdf.py, que además verifica el límite de páginas. La presentación se prepara durante la semana.

Los tres modelos ya están corridos con el vacío transversal: U(1) con tres semillas (secciones 3.4 y 3.6) y SU(2)×U(1) con una (sección 3.7). Lo que sigue:

Las tres decisiones sobre los parámetros quedaron tomadas el 22 de septiembre de 2026. Las razones están en Parámetros comparables:

  1. Intensidad de resonancia: q = 120 en lugar de 300.
  2. Con dos campos de gauge: a cada uno le toca la mitad (60 y 60), para que el total sea igual al del control.
  3. Campos extra: apagados, para que en cada modelo haya un solo canal que recibe la energía.

Decisiones confirmadas. La tabla con todos los valores está en Parámetros comparables.

Cuando esté la primera simulación, la primera verificación va a ser justamente lo que aprendí acá: que la ley de Gauss se cumpla desde el primer instante, y que el inflatón del modelo con gauge arranque oscilando igual que el del control.

6. Glosario

Campo
Una magnitud que tiene un valor en cada punto del espacio, como la temperatura en cada punto de una habitación. En física moderna, las partículas son "vibraciones" de campos.
Campo escalar
Un campo que en cada punto tiene un solo número, como la temperatura.
Campo de gauge
Un campo que transmite una fuerza entre partículas con carga. El campo electromagnético es uno. Tiene dirección y cumple la ley de Gauss.
U(1) y SU(2)
Los nombres matemáticos de dos tipos de campo de gauge. U(1) es el tipo del electromagnetismo. SU(2) es el de la fuerza débil, más complicado porque el campo interactúa consigo mismo.
Mezcla (fotón, Z y W)
Cuando un campo tiene carga de U(1) y de SU(2) a la vez, algunas combinaciones de los campos gauge se comportan como campos separados, cada uno con su masa. En el Modelo Estándar así aparecen el fotón (sin masa) y las partículas Z y W. En este proyecto pasa lo mismo con el inflatón (sección 3.5).
Inflación
Una expansión rapidísima que, según la teoría más aceptada, tuvo el universo en su primera fracción de segundo.
Inflatón
El campo que impulsó la inflación. Cuando la inflación terminó, quedó oscilando.
Recalentamiento (preheating)
La etapa en que el inflatón, al oscilar, le pasa su energía a los demás campos, de forma rápida y violenta.
q (parámetro de resonancia)
Qué tan fuerte "empuja" el inflatón al campo que recibe la energía, en cada oscilación. Decide en qué escala y qué tan rápido crece ese campo.
Resonancia
Cuando un empuje periódico coincide con el ritmo natural de algo y lo hace crecer cada vez más, como al empujar una hamaca en el momento justo.
Ondas gravitacionales
Ondulaciones del propio espacio que viajan a la velocidad de la luz.
Espectro
Cuánta señal hay en cada frecuencia. Es la "huella" que se quiere comparar entre modelos.
Red (lattice)
La grilla de puntos en que se divide el espacio para simularlo en una computadora.
Variables de programa
Las unidades propias que usa el programa para que los números queden cerca de 1.
Ley de Gauss
La regla de que las líneas de campo eléctrico sólo nacen o terminan donde hay carga. Tiene que cumplirse en todo momento.
Número complejo
Un par de números (parte real y parte imaginaria) que se manejan como uno solo. Se usan para describir campos con carga.
Control
La versión del experimento sin el ingrediente que se quiere estudiar. Acá, el modelo sin campos de gauge.
Provenance (procedencia)
El registro de dónde sale cada número y cada afirmación del proyecto.