ODEROM

Ordinary Differential Equations, Relativity and Other Mathematics
Vinte e duas deduções de Schutz, reproduzidas
Confrontado com
B. F. Schutz, A First Course in General Relativity
3ª edição, Cambridge University Press, 2022
Rafael C. R. de Lima
Universidade do Estado de Santa Catarina — CCT, Joinville
ORCID 0000-0003-1718-3838

Sumário

  1. O que este documento é
  2. Capítulo 5 — cálculo tensorial em coordenadas polares
  3. Capítulo 6 — variedades curvas
  4. Capítulo 10 — soluções esféricas para estrelas
  5. Capítulo 13 — cosmologia
  6. O que não funcionou, e o que foi feito
  7. Identidades e fatos estruturais — dez contas de outro tipo
  8. O laço que fechou

1. O que este documento é

Vinte e duas deduções tensoriais de A First Course in General Relativity (B. F. Schutz, 3ª ed., Cambridge, 2022), refeitas pelo ODEROM. Cada uma traz a seção e a página do livro, o documento .od completo, o comando, e a saída do programa — bytes reais, capturados do binário, não transcritos.

As contas foram escolhidas por serem afirmações verificáveis: o livro diz quanto vale alguma coisa, e o programa ou reproduz ou não. Duas delas são do tipo "one can show that", em que o autor pula a álgebra — e são justamente as que mais valem a pena.

Elas vêm em duas partes, e a divisão não é cronológica. As doze dos capítulos 2 a 5 são do tipo "calcule este tensor e compare com a fórmula": o livro dá uma expressão fechada e o programa tem de chegar nela. As dez da parte 7 são de outra natureza — identidades e fatos estruturais: simetrias do Riemann, as identidades de Bianchi, curvatura nula onde a conexão não é nula, matéria em espaço plano, e uma solução exata que não é esfericamente simétrica.

Como cada conta é conferida

Onde o livro dá uma fórmula fechada, ela é escrita como um tensor no próprio documento e subtraída do que o ODEROM calcula. Os dois lados passam pelo mesmo parser e pelo mesmo normalizador, e o que se cobra é que a diferença seja identicamente nula.

Comparar strings de saída provaria bem menos: passaria a depender de escolhas de renderização — se o programa escreve 1/r ou r^-1, se põe a exponencial no numerador ou no denominador — que não são o assunto. A diferença não depende de nada disso.

Onde o zero é fraco, está dito. Uma identidade que vale por construção não prova que o programa a calculou: se ∇ devolvesse zero para tudo, a divergência do Einstein seria nula de graça. Por isso as contas desse tipo vêm com um controle ao lado — uma quantidade que não é nula e cujo valor o livro também dá. Sem o controle, o zero não é evidência.

Como rodar o que está aqui

Cada conta aparece em dois blocos, que é como o caderno funciona: um com as declarações, e o seguinte com a pergunta. Copie o primeiro, Shift+Enter, copie o segundo, Shift+Enter. Onde há mais de uma pergunta, cada linha é um bloco.

Na linha de comando é outra grafia, e não é a que este documento mostra. O caderno pede eval V[a;a]; o terminal pede o arquivo e as aspas do shell:

oderom eval --prelude polar.od "V[a;a]"

Uma consulta sem expressão — christoffel, riemann, einstein — vira oderom christoffel polar.od. Colar a linha do terminal num bloco do caderno não funciona: oderom não é palavra da linguagem, e a recusa lista as que são.

Todo documento .od deste relatório está completo no texto. As vinte e duas contas também estão fixadas como testes em oderom-cli/tests/schutz.rs, com as mesmas referências de página, e rodam em cerca de sete segundos com cargo test -p oderom-cli --test schutz.

2. Capítulo 5 — cálculo tensorial em coordenadas polares

O plano euclidiano numa carta curvilínea: sem curvatura, mas com símbolos de Christoffel não nulos. É onde o livro separa "a conexão não é zero" de "o espaço é curvo".

2.1  Os símbolos de Christoffel em coordenadas polares  confere

Schutz: §5.4, p.127, Eq. 5.45

No plano euclidiano em coordenadas polares, três dos oito símbolos são não nulos: Γrθθ = −r e Γθrθ = Γθθr = 1/r. Schutz os obtém derivando os vetores de base (∂er/∂θ = eθ/r, ∂eθ/∂θ = −r er); aqui saem da métrica pela fórmula usual.

O documento — um bloco.

manifold M dim 2
bundle TM on M dim 2
chart pol on M coords (r, theta)
metric g on pol bundle TM { [r,r] = 1, [theta,theta] = r^2 }

A pergunta — o bloco seguinte, e a resposta.

christoffel
Gamma[^r,theta,theta] = -r
Gamma[^theta,r,theta] = r^-1
Gamma[^theta,theta,r] = r^-1
5 independent components identically zero

Os três do livro, com os mesmos sinais, e a confirmação de que os outros cinco se anulam — que é metade da afirmação e a metade que costuma ficar sem conferir.

2.2  A divergência de um vetor em polares  confere

Schutz: §5.3, p.129, Eq. 5.56

Vα;α = ∂Vr/∂r + ∂Vθ/∂θ + Vr/r. O terceiro termo é o que a derivada parcial não dá, e vem de Γαrα = 1/r.

O documento — um bloco.

manifold M dim 2
bundle TM on M dim 2
chart pol on M coords (r, theta)
metric g on pol bundle TM { [r,r] = 1, [theta,theta] = r^2 }
tensor V : TM on pol { [r] = A(r,theta), [theta] = B(r,theta) }

A pergunta — o bloco seguinte, e a resposta.

eval V[a;a]
(r*A_r(r,theta) + r*B_theta(r,theta) + A(r,theta))/r

Dividindo por r: A_r + B_theta + A/r, que é a Eq. 5.56. As componentes são funções indeterminadas das duas coordenadas de propósito — com um vetor concreto a conta fecharia por acidente aritmético em vez de reproduzir a fórmula.

2.3  O laplaciano em polares  confere

Schutz: §5.3, p.129, Eq. 5.57

∇²φ = (1/r) ∂r(r ∂rφ) + (1/r²) ∂²θφ. O caminho do livro é: converter a 1-forma gradiente em vetor, o que dá componentes (φ,r, φ,θ/r²), e aplicar a Eq. 5.56.

O documento — um bloco.

manifold M dim 2
bundle TM on M dim 2
chart pol on M coords (r, theta)
metric g on pol bundle TM { [r,r] = 1, [theta,theta] = r^2 }
tensor D : TM on pol { [r] = phi_{r}(r,theta), [theta] = phi_{theta}(r,theta)/r^2 }

A pergunta — o bloco seguinte, e a resposta.

eval D[a;a]
(r*phi_r(r,theta) + r^2*phi_rr(r,theta) + phi_thetatheta(r,theta))/r^2

Dividindo por r^2: phi_rr + phi_r/r + phi_thetatheta/r^2, que é a Eq. 5.57 com o primeiro termo expandido. O phi_{r}(r,theta) do documento é a notação de subscrito de derivada do ODEROM — a derivada de phi em relação ao seu primeiro argumento, tratada como símbolo opaco, que é exatamente o estatuto que ela tem aqui.

3. Capítulo 6 — variedades curvas

A curvatura propriamente dita: o Riemann, o que ele significa (o comutador de derivadas covariantes), e a identidade que sustenta as equações de campo.

3.1  O Riemann e a curvatura da esfera  confere

Schutz: Exercícios 6.28–6.29, p.167

Na esfera de raio a, a única componente independente é Rθφθφ = a² sin²θ, e o escalar de Ricci é 2/a² — duas vezes a curvatura gaussiana 1/a², como tem de ser em duas dimensões.

O documento — um bloco.

manifold M dim 2
bundle TM on M dim 2
chart s on M coords (theta, phi)
metric g on s bundle TM { [theta,theta] = a^2, [phi,phi] = a^2*sin(theta)^2 }
tensor Ric := ricci g

A pergunta — o bloco seguinte, e a resposta.

riemann
eval Ric[a,a]
R[theta,phi,theta,phi] = a^2*sin(theta)^2
  (4 components by symmetry)

2/a^2

O escalar sai do traço, Ric[a,a] = gμνRμν, que é a definição do próprio livro (Eq. 6.92). Pedir tensor Rs := scalar g é recusado pelo programa, e com razão: scalar devolve um escalar, e tensor declara tensor.

3.2  O comutador de derivadas covariantes É o Riemann  confere

Schutz: §6.5, p.160, Eq. 6.77

[∇α, ∇β] Vμ = Rμναβ Vν. Descendo o índice livre — o que é legítimo porque ∇g = 0 faz subir e descer comutar com derivar, o argumento do próprio Schutz logo abaixo da Eq. 6.78 — a igualdade vira [∇α, ∇β] Wμ = Rμναβ Vν.

O documento — um bloco.

manifold M dim 2
bundle TM on M dim 2
chart s on M coords (theta, phi)
metric g on s bundle TM { [theta,theta] = a^2, [phi,phi] = a^2*sin(theta)^2 }
tensor W : TM* on s { [theta] = P(theta,phi), [phi] = Q(theta,phi) }
tensor V : TM  on s { [theta] = P(theta,phi)/a^2, [phi] = Q(theta,phi)/(a^2*sin(theta)^2) }
tensor R := riemann g

A pergunta — o bloco seguinte, e a resposta.

eval W[m;b,a] - W[m;a,b]
eval W[m;b,a] - W[m;a,b] - R[m,n,a,b] V[n]
[theta,theta,phi] = -Q(theta,phi)
[theta,phi,theta] = Q(theta,phi)
[phi,theta,phi] = sin(theta)^2*P(theta,phi)
[phi,phi,theta] = -sin(theta)^2*P(theta,phi)
4 independent components identically zero

8 independent components identically zero

A primeira saída mostra que o comutador tem conteúdo — quatro das oito células são não nulas —, e a segunda que ele é exatamente o Riemann contraído. Sem a primeira, a segunda não provaria nada: uma segunda derivada que devolvesse zero para tudo passaria igual.

O campo tem componentes indeterminadas P, Q, então nenhuma célula fecha por acidente. Esta é a conta que exercita a segunda derivada covariante, W[m;b,a], com os dois índices de derivada em ordens trocadas.

3.3  A divergência do tensor de Einstein é nula  confere

Schutz: §6.6, p.163, Eq. 6.99

Gαβ;β = 0, a identidade de Bianchi duas vezes contraída. É ela que permite escrever G = 8πT: o lado esquerdo é livre de divergência por identidade, e o direito por conservação.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart frw on M coords (t, r, theta, phi)
metric g on frw bundle TM {
  [t,t] = -1,
  [r,r] = Scale(t)^2/(1 - k*r^2),
  [theta,theta] = Scale(t)^2*r^2,
  [phi,phi] = Scale(t)^2*r^2*sin(theta)^2
}
tensor G := einstein g
tensor Ric := ricci g

A pergunta — o bloco seguinte, e a resposta.

eval G[a,b;b]
eval Ric[a,b;b]
4 independent components identically zero

[t] = (-6*k*Scale'(t) + 3*Scale(t)*Scale'(t)*Scale''(t) + 3*Scale(t)^2*Scale'''(t) - 6*Scale'(t)^3)/Scale(t)^3
3 independent components identically zero

O controle está na segunda saída, e é o que faz a primeira valer alguma coisa. A divergência do Ricci NÃO é nula — o próprio livro diz quanto ela vale, ½R,λ (Eq. 6.96). Se o programa devolvesse zero para as duas, o zero da primeira não seria prova de nada.

A métrica é FRW e não Schwarzschild justamente por isso: em vácuo G já é nulo componente a componente, e a divergência de zero é zero sem que ∇ tenha feito trabalho nenhum.

4. Capítulo 10 — soluções esféricas para estrelas

A conta central de todo curso de relatividade: o tensor de Einstein da métrica estática esfericamente simétrica, e o que ele dá quando igualado à matéria.

4.1  O tensor de Einstein da métrica estática esfericamente simétrica  confere

Schutz: §10.2, p.271, Eqs. 10.14–10.17

Para ds² = −e2Φdt² + e2Λdr² + r²dΩ², o livro diz "one can show that" e escreve as quatro componentes:

Esta é a conta principal do capítulo, e o "one can show" é o que este documento existe para mostrar.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart sph on M coords (t, r, theta, phi)
metric g on sph bundle TM {
  [t,t] = -exp(2*Phi(r)),
  [r,r] = exp(2*Lambda(r)),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor G := einstein g
tensor S : TM*, TM* on sph {
  [t,t] = exp(2*Phi(r))/r^2 * diff(r*(1 - exp(-2*Lambda(r))), r),
  [r,r] = -exp(2*Lambda(r))*(1 - exp(-2*Lambda(r)))/r^2 + 2*Phi'(r)/r,
  [theta,theta] = r^2*exp(-2*Lambda(r))*(Phi''(r) + Phi'(r)^2 + Phi'(r)/r - Phi'(r)*Lambda'(r) - Lambda'(r)/r),
  [phi,phi] = sin(theta)^2 * r^2*exp(-2*Lambda(r))*(Phi''(r) + Phi'(r)^2 + Phi'(r)/r - Phi'(r)*Lambda'(r) - Lambda'(r)/r)
}

A pergunta — o bloco seguinte, e a resposta.

einstein
eval G[a,b] - S[a,b]
G[t,t] = (2*r*exp(2*Phi(r))*Lambda'(r) + exp(2*Lambda(r))*exp(2*Phi(r)) - exp(2*Phi(r)))/(r^2*exp(2*Lambda(r)))
G[r,r] = (1 + 2*r*Phi'(r) - exp(2*Lambda(r)))/r^2
G[theta,theta] = (-r*Lambda'(r) + r*Phi'(r) - r^2*Lambda'(r)*Phi'(r) + r^2*Phi'(r)^2 + r^2*Phi''(r))/exp(2*Lambda(r))
G[phi,phi] = (-r*sin(theta)^2*Lambda'(r) + ... + r^2*sin(theta)^2*Phi''(r))/exp(2*Lambda(r))
6 independent components identically zero

16 independent components identically zero

Dezesseis de dezesseis nulas. O tensor S é o do livro escrito literalmente, incluindo a derivada d/dr[r(1 − e^{−2Λ})] da Eq. 10.14, que fica a cargo de diff — nada foi expandido à mão de um lado para bater com o outro. A conferência é a diferença dos dois tensores, e não a comparação das strings de saída: assim ela não depende de escolhas de renderização, que não são o assunto.

Esta conta encontrou um defeito. Escrever a Eq. 10.14 exigia diff, que o manual documenta e que a recusa de sin'(x) manda usar — e que, até esta rodada, virava um símbolo opaco chamado diff em vez de derivar. Ver §6.1.

4.2  A geometria exterior: Schwarzschild é vácuo  confere

Schutz: §10.4, p.273

Fora da estrela, ρ = p = 0, e a solução tem de satisfazer Gαβ = 0.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart schw on M coords (t, r, theta, phi)
metric g on schw bundle TM {
  [t,t] = -(1 - 2*Mass/r),
  [r,r] = 1/(1 - 2*Mass/r),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}

A pergunta — o bloco seguinte, e a resposta.

einstein
10 independent components identically zero

As dez independentes, todas nulas. É a conta mais barata do documento e a que serve de sanidade para todas as outras: se esta falhasse, nenhuma das demais valeria discussão.

4.3  A equação de equilíbrio hidrostático relativístico  confere

Schutz: §10.3, p.272, Eqs. 10.26–10.27

De Tαβ;β = 0, com o fluido em repouso na métrica estática, sai (ρ + p) dΦ/dr = −dp/dr. O livro observa que, das quatro equações, só a de α = r não se anula identicamente.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart sph on M coords (t, r, theta, phi)
metric g on sph bundle TM {
  [t,t] = -exp(2*Phi(r)),
  [r,r] = exp(2*Lambda(r)),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor T : TM, TM on sph {
  [t,t] = rho(r)*exp(-2*Phi(r)),
  [r,r] = p(r)*exp(-2*Lambda(r)),
  [theta,theta] = p(r)/r^2,
  [phi,phi] = p(r)/(r^2*sin(theta)^2)
}

A pergunta — o bloco seguinte, e a resposta.

eval T[a,b;b]
[^r] = (Phi'(r)*p(r) + Phi'(r)*rho(r) + p'(r))/exp(2*Lambda(r))
3 independent components identically zero

Uma só componente não nula, a de r, exatamente como o livro diz. Igualada a zero e multiplicada por e2Λ: Φ′(p + ρ) + p′ = 0, que é a Eq. 10.27.

Esta conta encontrou o outro defeito, e o mais interessante. Antes desta rodada a saída era (r*exp(-2Λ)*exp(2Λ)*Φ'*p + ... + 2*exp(-2Λ)*exp(2Λ)*p - 2*p)/(r*exp(2Λ)): o par métrica/inversa sobrevivia intacto em cada termo, e dois termos que deviam se cancelar ficavam no resultado. Não era resposta errada — era resposta numa forma que esconde o cancelamento que a conta inteira existe para mostrar. Ver §6.2.

5. Capítulo 13 — cosmologia

A mesma máquina, aplicada ao universo inteiro: a métrica FRW, a equação de Friedmann e a conservação da matéria.

5.1  O Einstein tridimensional da hipersuperfície  confere

Schutz: §13.2, p.424, Eq. 13.9

Ao construir a métrica cosmológica, Schutz precisa do tensor de Einstein da hipersuperfície espacial dl² = e2Λ(r)dr² + r²dΩ², e afirma que ele se obtém do quadridimensional (Eqs. 10.15–10.17) pondo Φ = 0: Grr = −(1/r²)e2Λ(1 − e−2Λ), Gθθ = −r e−2ΛΛ′, Gφφ = sin²θ Gθθ.

É uma afirmação sobre duas contas diferentes — uma em três dimensões, outra em quatro — e vale conferir por isso.

O documento — um bloco.

manifold M dim 3
bundle TM on M dim 3
chart esp on M coords (r, theta, phi)
metric h on esp bundle TM {
  [r,r] = exp(2*Lambda(r)),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor G := einstein h
tensor S : TM*, TM* on esp {
  [r,r] = -exp(2*Lambda(r))*(1 - exp(-2*Lambda(r)))/r^2,
  [theta,theta] = -r*exp(-2*Lambda(r))*Lambda'(r),
  [phi,phi] = -sin(theta)^2*r*exp(-2*Lambda(r))*Lambda'(r)
}

A pergunta — o bloco seguinte, e a resposta.

einstein
eval G[a,b] - S[a,b]
G[r,r] = (1 - exp(2*Lambda(r)))/r^2
G[theta,theta] = -r*Lambda'(r)/exp(2*Lambda(r))
G[phi,phi] = -r*sin(theta)^2*Lambda'(r)/exp(2*Lambda(r))
3 independent components identically zero

9 independent components identically zero

Nove de nove nulas: a conta em três dimensões dá o mesmo que a de quatro com Φ = 0, e o atalho do livro está certo.

5.2  A componente temporal do Einstein em FRW  confere

Schutz: §13.3, p.439, Eq. 13.51

Gtt = 3(Ṙ/R)² + 3k/R². É a única componente que a cosmologia precisa calcular: a isotropia mata as mistas, e a identidade de Bianchi liga a espacial a esta.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart frw on M coords (t, r, theta, phi)
metric g on frw bundle TM {
  [t,t] = -1,
  [r,r] = Scale(t)^2/(1 - k*r^2),
  [theta,theta] = Scale(t)^2*r^2,
  [phi,phi] = Scale(t)^2*r^2*sin(theta)^2
}
tensor G := einstein g
tensor S : TM*, TM* on frw { [t,t] = 3*diff(Scale(t), t)^2/Scale(t)^2 + 3*k/Scale(t)^2 }

A pergunta — o bloco seguinte, e a resposta.

eval G[a,b]
eval G[a,b] - S[a,b]
[t,t] = (3*k + 3*Scale'(t)^2)/Scale(t)^2
[r,r] = (-k - 2*Scale(t)*Scale''(t) - Scale'(t)^2)/(1 - k*r^2)
[theta,theta] = -k*r^2 - 2*r^2*Scale(t)*Scale''(t) - r^2*Scale'(t)^2
[phi,phi] = -k*r^2*sin(theta)^2 - 2*r^2*sin(theta)^2*Scale(t)*Scale''(t) - r^2*sin(theta)^2*Scale'(t)^2
12 independent components identically zero

(3k + 3Ṙ²)/R² é a Eq. 13.51. Na segunda chamada, a componente [t,t] desaparece da lista de não nulas — as três que sobram são as espaciais, que S não declara.

As doze mistas nulas confirmam de passagem a outra afirmação do livro, a de que a isotropia garante Gtj = 0.

5.3  A equação de movimento da matéria  confere

Schutz: §13.3, p.439, Eq. 13.47

De Tμν;ν = 0 em FRW sai d(ρR³)/dt = −p d(R³)/dt: a taxa de variação da energia de um elemento de fluido é o trabalho que ele faz ao se expandir. Schutz nota que, por isotropia, as componentes espaciais se anulam identicamente.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart frw on M coords (t, r, theta, phi)
metric g on frw bundle TM {
  [t,t] = -1,
  [r,r] = Scale(t)^2/(1 - k*r^2),
  [theta,theta] = Scale(t)^2*r^2,
  [phi,phi] = Scale(t)^2*r^2*sin(theta)^2
}
tensor T : TM, TM on frw {
  [t,t] = rho(t),
  [r,r] = p(t)*(1 - k*r^2)/Scale(t)^2,
  [theta,theta] = p(t)/(Scale(t)^2*r^2),
  [phi,phi] = p(t)/(Scale(t)^2*r^2*sin(theta)^2)
}

A pergunta — o bloco seguinte, e a resposta.

eval T[a,b;b]
[^t] = (Scale(t)*rho'(t) + 3*Scale'(t)*p(t) + 3*Scale'(t)*rho(t))/Scale(t)
3 independent components identically zero

Uma componente não nula, a temporal, e as três espaciais nulas — as duas metades da afirmação. Dividindo por Scale(t): ρ̇ + 3(Ṙ/R)(ρ + p) = 0. Multiplicando por R³: ρ̇R³ + 3ρR²Ṙ + 3pR²Ṙ = 0, que é d(ρR³)/dt = −p d(R³)/dt, a Eq. 13.47.

O caso da poeira (p = 0) dá d(ρR³)/dt = 0, e o da radiação (p = ρ/3) dá d(ρR⁴)/dt = 0 — as Eqs. 13.48 e 13.50, que saem desta por substituição.

6. O que não funcionou, e o que foi feito

Duas das doze contas não saíam. Nenhuma das duas por falta de recurso no programa: as duas por defeito, e uma delas silencioso.

6.1  diff era um símbolo opaco

Escrever a Eq. 10.14 como o livro a escreve exige a derivada d/dr[r(1 − e−2Λ)]. O manual documenta diff(f(r), r) na §9.10, e a recusa de sin'(x) diz, com todas as letras, "write diff(sin(...), var)".

Escrever isso num documento produzia:

diff(sin(x), x)   ->   diff(sin(x),x)

Um símbolo opaco de dois argumentos chamado diff, jamais derivado. Quem seguisse a mensagem de erro recebia uma resposta de aparência plausível e silenciosamente errada — exatamente a classe de falha que a lista de nomes reservados do projeto existe para impedir no caso de tan.

Resolvido: diff(EXPR, VAR) agora aplica a derivada, ligada ao diff que o motor já tinha. O segundo argumento é um nome de variável e só isso — diff(f(x), x+1) é recusado nomeando a grafia certa, em vez de tropeçar num ) faltando.

diff(sin(x), x)          ->  cos(x)
diff(f(x)^2, x)          ->  2*f(x)*f'(x)
diff(f(x)*h(x), x)       ->  f(x)*h'(x) + f'(x)*h(x)
diff(diff(f(x), x), x)   ->  f''(x)
diff(f(x), y)            ->  0

6.2  exp e a equação TOV

O motor tratava exp(u) como átomo opaco, sem relação nenhuma com exp(−u). Numa métrica estática isso é fatal de um jeito particular: g_rr = e2Λ e a inversa traz e−2Λ, e toda divergência multiplica os dois. A TOV saía assim:

(r*exp(-2*Lambda(r))*exp(2*Lambda(r))*Phi'(r)*p(r) + ...
 + 2*exp(-2*Lambda(r))*exp(2*Lambda(r))*p(r) - 2*p(r))/(r*exp(2*Lambda(r)))

O par intacto em cada termo, e os dois últimos — que se cancelam — de pé no resultado. Resposta certa, numa forma que esconde o cancelamento que a conta existe para mostrar.

A primeira tentativa, e por que ela era pior que o problema

A regra óbvia é exp(a)·exp(b) = exp(a+b), aplicada na multiplicação de monômios. Ela fez a TOV fechar — e quebrou o resto. Reprodutor mínimo:

(exp(x) + exp(y))^2

2*exp(x)*exp(y)*exp(x + y)^4*exp(2*x + 2*y)^3*exp(4*x + 4*y)^3
  *exp(8*x + 8*y)^3*...*exp(1024*x + 1024*y)

O argumento dobrando até 1024, e com valor errado. A causa é estrutural e o comentário que a regra tinha sido deixada de fora já a antecipava: exp(x), exp(y), exp(x+y) e exp(2x+2y) são geradores algebricamente dependentes, e o anel de polinômios sobre o qual o MDC trabalha supõe geradores independentes. Cada rodada de redução fundia o que a anterior havia criado. O tensor de Einstein da §10.2 saía errado por isso.

O que resolve

Sinal canônico no argumento: exp(−u) é internado como o mesmo gerador que exp(u), com expoente −1. Não cria gerador nenhum — apenas deixa de criar um a mais — e quem corta o par é o MDC comum que já existia.

exp(x)*exp(-x)       ->  1
exp(x-y)*exp(y-x)    ->  1
exp(x)^3*exp(-x)^2   ->  exp(x)
(exp(x)+exp(y))^2    ->  2*exp(x)*exp(y) + exp(x)^2 + exp(y)^2

E a TOV fecha:

[^r] = (Phi'(r)*p(r) + Phi'(r)*rho(r) + p'(r))/exp(2*Lambda(r))

6.3  O que continua em aberto

exp(2x)/exp(x) não reduz. O sinal canônico junta u com −u; não junta u com 2u. Fechar isso significa extrair o conteúdo inteiro do argumento — exp(2u) → exp(u)² —, o que é uma decisão de representação e não um remendo: põe um cálculo de conteúdo em toda internação de exp, que é caminho quente, e muda a grafia de toda saída com exponencial (exp(2*Lambda(r)) viraria exp(Lambda(r))^2, mais longe do que o livro escreve). Nenhuma das doze contas precisa disso, e o limite está fixado por um teste que falha se alguém o fechar sem atualizar a decisão.

Duas outras contas do livro ficaram de fora por não serem do tipo que este programa responde. A §8.3 (campo fraco) pede expansão em série, e o ODEROM não expande em série. A §7.4 (quantidades conservadas) pede vetores de Killing, que não existem como consulta.

7. Identidades e fatos estruturais — dez contas de outro tipo

As doze anteriores comparavam um tensor calculado com uma fórmula do livro. Estas dez são de outra natureza: identidades que o Riemann satisfaz por construção, curvatura nula onde a conexão não é nula, matéria em espaço plano, e uma solução exata sem simetria esférica.

7.1  Curvatura nula onde a conexão não é nula  confere

Schutz: §6.5, p.159, logo abaixo da Eq. 6.71; Exercício 6.30, p.167

Rαβμν = 0 ⟺ variedade plana. Schutz sugere entre parênteses: "try showing that this is true in polar coordinates for the Euclidean plane", e o Exercício 6.30 pede o mesmo para o cilindro.

É a conta que separa "a conexão não é nula" de "o espaço é curvo". Em polares os três símbolos de Christoffel da §2.1 são não nulos, e mesmo assim o Riemann se anula: os termos quadráticos ΓΓ cancelam exatamente as derivadas ∂Γ.

O documento — um bloco.

manifold M dim 2
bundle TM on M dim 2
chart pol on M coords (r, theta)
metric g on pol bundle TM { [r,r] = 1, [theta,theta] = r^2 }
tensor R := riemann g

# e o cilindro, num documento separado:
manifold M dim 2
bundle TM on M dim 2
chart cil on M coords (z, phi)
metric g on cil bundle TM { [z,z] = 1, [phi,phi] = a^2 }
tensor R := riemann g

A pergunta — o bloco seguinte, e a resposta.

eval R[a,b,c,d]
eval R[a,b,c,d]
16 independent components identically zero

16 independent components identically zero

O controle está no teste, e é a esfera: a MESMA máquina, contra a^2*sin(theta)^2, não dá zero (§3.1). Sem ele, um riemann que devolvesse zero sempre passaria nos dois.

É o teste mais afiado deste documento para uma classe específica de defeito: apagar os termos quadráticos ΓΓ do Riemann deixa o cilindro passando — ele é plano por coeficientes constantes — e derruba o plano em polares na hora. Foi conferido assim, sabotando.

7.2  A três-esfera tem curvatura escalar constante  confere

Schutz: Exercício 6.33, p.167

A três-esfera de raio a, em coordenadas hiperesféricas: gχχ = a², gθθ = a² sin²χ, gφφ = a² sin²χ sin²θ. A curvatura escalar é 6/a².

Constante, e é isso que faz dela um espaço homogêneo e isotrópico — o caso k = +1 da cosmologia do capítulo 13.

O documento — um bloco.

manifold M dim 3
bundle TM on M dim 3
chart s3 on M coords (chi, theta, phi)
metric g on s3 bundle TM {
  [chi,chi] = a^2,
  [theta,theta] = a^2*sin(chi)^2,
  [phi,phi] = a^2*sin(chi)^2*sin(theta)^2
}
tensor Ric := ricci g

A pergunta — o bloco seguinte, e a resposta.

eval Ric[a,a]
6/a^2

Sem χ nem θ na resposta, que é metade da afirmação: a curvatura é a mesma em todo ponto.

7.3  A divergência pela raiz do determinante  confere

Schutz: §6.3, p.151, Eqs. 6.40 e 6.42

Vα;α = (1/√|g|) (√|g| Vα),α.

Ela sai de Γαμα = (√−g),μ/√−g (Eq. 6.40): o traço do Christoffel é a derivada logarítmica do determinante da métrica. É a forma que se usa na prática, porque dispensa calcular Γ.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart schw on M coords (t, r, theta, phi)
metric g on schw bundle TM {
  [t,t] = -(1 - 2*Mass/r),
  [r,r] = 1/(1 - 2*Mass/r),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor V : TM on schw { [t] = A(t,r), [r] = B(t,r), [theta] = C(theta), [phi] = D(phi) }
raiz := sqrt(r^4*sin(theta)^2)
tensor S : TM on schw {
  [t] = (diff(raiz*A(t,r), t) + diff(raiz*B(t,r), r)
       + diff(raiz*C(theta), theta) + diff(raiz*D(phi), phi))/raiz
}

A pergunta — o bloco seguinte, e a resposta.

eval V[a;a]
eval S[a]
(r*sin(theta)*A_t(t,r) + r*sin(theta)*B_r(t,r) + r*sin(theta)*C'(theta)
 + r*sin(theta)*D'(phi) + r*cos(theta)*C(theta) + 2*sin(theta)*B(t,r))/(r*sin(theta))

[^t] = (r*sin(theta)*A_t(t,r) + r*sin(theta)*B_r(t,r) + r*sin(theta)*C'(theta)
      + r*sin(theta)*D'(phi) + r*cos(theta)*C(theta) + 2*sin(theta)*B(t,r))/(r*sin(theta))

Idênticas, caractere por caractere — e calculadas por caminhos que não se tocam: a primeira pelos símbolos de Christoffel, a segunda por sqrt e diff. Em Schwarzschild −g = r⁴sin²θ.

Os dois últimos termos são os que a derivada parcial sozinha não dá: r*cos(theta)*C(theta) e 2*sin(theta)*B(t,r), que vêm inteiros da raiz do determinante.

7.4  O fluido perfeito, da forma invariante à diagonal  confere

Schutz: §4.7, p.100, Eqs. 4.36–4.38

A forma invariante é Tαβ = (ρ+p)UαUβ + p ηαβ (Eq. 4.37), e no referencial de repouso ela tem de dar T = diag(ρ, p, p, p) (Eq. 4.36).

Schutz verifica isso à mão, componente a componente: "if α = β = 0 then U⁰ = 1, η₀₀ = −1, and Tαβ = (ρ + p) − p = ρ... by trying all possible α and β you can verify".

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart mink on M coords (t, x, y, z)
metric g on mink bundle TM { [t,t] = -1, [x,x] = 1, [y,y] = 1, [z,z] = 1 }
tensor U : TM on mink { [t] = 1 }
tensor T^{\mu\nu} := (rho + p) U^{\mu} U^{\nu} + (p) g^{\mu\nu}

A pergunta — o bloco seguinte, e a resposta.

eval T[a,b]
eval T[a,a]
eval T[a,b] U[a] U[b]
[^t,^t] = rho
[^x,^x] = p
[^y,^y] = p
[^z,^z] = p
12 independent components identically zero

3*p - rho

rho

As dezesseis componentes, e as doze fora da diagonal nulas — o "by trying all possible α and β" feito de uma vez. O traço 3p − ρ e a densidade que o próprio fluido mede, ρ, saem da mesma declaração.

Esta conta não podia ser escrita até a rodada passada. Um monômio só aceitava coeficiente racional, e (rho + p) é simbólico. O coeficiente escalar entre parênteses fecha isso; a §8 conta o que era o problema.

7.5  As simetrias do tensor de Riemann  confere

Schutz: §6.5, p.158, Eqs. 6.69 e 6.70

Rαβμν = −Rβαμν = −Rαβνμ = Rμναβ  (6.69), e Rαβμν + Rανβμ + Rαμνβ = 0  (6.70).

São elas que reduzem as 256 componentes de um tensor de rank 4 em quatro dimensões às 20 independentes.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart schw on M coords (t, r, theta, phi)
metric g on schw bundle TM {
  [t,t] = -(1 - 2*Mass/r),
  [r,r] = 1/(1 - 2*Mass/r),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor R := riemann g

A pergunta — o bloco seguinte, e a resposta.

eval R[a,b,c,d] + R[b,a,c,d]
eval R[a,b,c,d] + R[a,b,d,c]
eval R[a,b,c,d] - R[c,d,a,b]
eval R[a,b,c,d] + R[a,d,b,c] + R[a,c,d,b]
256 independent components identically zero
256 independent components identically zero
256 independent components identically zero
256 independent components identically zero

Schwarzschild tem 24 células não nulas no Riemann, então nenhuma das quatro identidades fecha por vacuidade — o teste confere isso antes.

7.6  As identidades de Bianchi, na forma diferencial  confere

Schutz: §6.6, p.162, Eq. 6.90

Rαβμν;λ + Rαβλμ;ν + Rαβνλ;μ = 0.

É a forma de onde tudo o mais vem: contraída uma vez dá a Eq. 6.93, contraída duas vezes dá ∇·G = 0 (§3.3), e é por causa dela que as equações de Einstein são compatíveis com a conservação da energia.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart schw on M coords (t, r, theta, phi)
metric g on schw bundle TM {
  [t,t] = -(1 - 2*Mass/r),
  [r,r] = 1/(1 - 2*Mass/r),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor R := riemann g

A pergunta — o bloco seguinte, e a resposta.

eval R[a,b,c,d;e] + R[a,b,d,e;c] + R[a,b,e,c;d]
(491.984 ms)
1024 independent components identically zero

Mil e vinte e quatro células, cada uma uma derivada covariante de um tensor de rank 4 — a conta mais pesada deste documento, e meio segundo.

7.7  O traço do Einstein espacial é constante  confere

Schutz: §13.2, p.425, Eq. 13.11

A condição de homogeneidade da cosmologia: o traço do tensor de Einstein tridimensional tem de ser uma constante κ. Para grr = 1/(1 − k r²) ele vale −3k.

É de onde Schutz tira a definição k := −κ/3, e com ela a métrica espacial da Eq. 13.13.

O documento — um bloco.

manifold M dim 3
bundle TM on M dim 3
chart esp on M coords (r, theta, phi)
metric h on esp bundle TM {
  [r,r] = 1/(1 - k*r^2),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor G := einstein h

A pergunta — o bloco seguinte, e a resposta.

eval G[a,a]
-3*k

Sem r na resposta, que é a metade da afirmação que importa: a curvatura é a mesma em todo ponto, e é isso que "homogêneo" quer dizer.

7.8  A constante cosmológica é um fluido de pressão negativa  confere

Schutz: §13.3, p.440, Eqs. 13.53–13.54

TΛαβ = −(Λ/8π) gαβ tem ρΛ = Λ/8π e pΛ = −ρΛ.

A pressão negativa é o ponto inteiro — é ela que acelera a expansão.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart frw on M coords (t, r, theta, phi)
metric g on frw bundle TM {
  [t,t] = -1,
  [r,r] = Scale(t)^2/(1 - k*r^2),
  [theta,theta] = Scale(t)^2*r^2,
  [phi,phi] = Scale(t)^2*r^2*sin(theta)^2
}
tensor U : TM on frw { [t] = 1 }
tensor TL : TM, TM on frw {
  [t,t] = Lam/(8*pi),
  [r,r] = -Lam*(1 - k*r^2)/(8*pi*Scale(t)^2),
  [theta,theta] = -Lam/(8*pi*Scale(t)^2*r^2),
  [phi,phi] = -Lam/(8*pi*Scale(t)^2*r^2*sin(theta)^2)
}

A pergunta — o bloco seguinte, e a resposta.

eval TL[a,b] U[a] U[b]
eval TL[a,a]
eval TL[a,b;b]
Lam/(8*pi)

-Lam/(2*pi)

4 independent components identically zero

A primeira é ρΛ = Λ/8π. A segunda é o traço 3p − ρ, e −Λ/2π = −4·(Λ/8π) só fecha com p = −ρ. A terceira é a conservação, que vale de graça porque ∇g = 0.

7.9  A métrica de Kerr é vácuo  confere

Schutz: §11.3, p.328, Eq. 11.71

O buraco negro em rotação, em coordenadas de Boyer–Lindquist, com Δ = r² − 2Mr + a² e ρ² = r² + a²cos²θ. É solução de vácuo: Rαβ = 0.

É a única solução exata deste documento que não é esfericamente simétrica: tem termo cruzado gtφ — o arrasto de referenciais — e um denominador que depende de duas coordenadas.

O documento — um bloco.

Sigma := r^2 + a^2*cos(theta)^2
Delta := r^2 - 2*M*r + a^2

manifold M dim 4
bundle TM on M dim 4
chart bl on M coords (t, r, theta, phi)
metric g on bl bundle TM {
  [t,t] = -(1 - 2*M*r/Sigma),
  [t,phi] = -2*M*a*r*sin(theta)^2/Sigma,
  [r,r] = Sigma/Delta,
  [theta,theta] = Sigma,
  [phi,phi] = (r^2 + a^2 + 2*M*a^2*r*sin(theta)^2/Sigma) * sin(theta)^2
}
tensor Ric := ricci g

A pergunta — o bloco seguinte, e a resposta.

eval Ric[a,b]
motor: localizado
16 independent components identically zero

Menos de um segundo. A linha motor: localizado diz qual dos dois motores rodou: o denominador bivariado de Kerr é justamente o caso que a forma racional geral não fecha, e para o qual existe o motor localizado.

O documento acima é examples/kerr.od, o mesmo que o resto da suíte usa — não uma cópia que possa divergir dele.

7.10  A divergência de um tensor antissimétrico  confere

Schutz: Exercício 6.34(c), p.166

Para Fμν antissimétrico, Fμν;ν = (√−g Fμν),ν/√−g.

É a divergência de Maxwell em espaço curvo, e a razão de as equações do campo eletromagnético não precisarem de símbolo de Christoffel nenhum. A identidade só vale por causa da antissimetria: os termos de Christoffel que sobrariam são simétricos nos dois índices e morrem contra ela.

O documento — um bloco.

manifold M dim 4
bundle TM on M dim 4
chart schw on M coords (t, r, theta, phi)
metric g on schw bundle TM {
  [t,t] = -(1 - 2*Mass/r),
  [r,r] = 1/(1 - 2*Mass/r),
  [theta,theta] = r^2,
  [phi,phi] = r^2 * sin(theta)^2
}
tensor F : TM, TM on schw {
  [t,r] = A(t,r,theta,phi),       [r,t] = -A(t,r,theta,phi),
  [t,theta] = B(t,r,theta,phi),   [theta,t] = -B(t,r,theta,phi),
  [t,phi] = C(t,r,theta,phi),     [phi,t] = -C(t,r,theta,phi),
  [r,theta] = D(t,r,theta,phi),   [theta,r] = -D(t,r,theta,phi),
  [r,phi] = E(t,r,theta,phi),     [phi,r] = -E(t,r,theta,phi),
  [theta,phi] = H(t,r,theta,phi), [phi,theta] = -H(t,r,theta,phi)
}
raiz := sqrt(r^4*sin(theta)^2)
tensor S : TM on schw {
  [t]     = (diff(raiz*A(..), r) + diff(raiz*B(..), theta) + diff(raiz*C(..), phi))/raiz,
  [r]     = (diff(-raiz*A(..), t) + diff(raiz*D(..), theta) + diff(raiz*E(..), phi))/raiz,
  [theta] = (diff(-raiz*B(..), t) + diff(-raiz*D(..), r) + diff(raiz*H(..), phi))/raiz,
  [phi]   = (diff(-raiz*C(..), t) + diff(-raiz*E(..), r) + diff(-raiz*H(..), theta))/raiz
}

A pergunta — o bloco seguinte, e a resposta.

eval F[a,b;b] - S[a]
4 independent components identically zero

As seis componentes independentes de F são funções indeterminadas das quatro coordenadas — nada se anula por acaso, e a divergência sozinha não é nula (o teste confere isso antes). Acima (..) abrevia (t,r,theta,phi), que no arquivo real vai escrito por extenso.

8. O laço que fechou

Uma das dez não pôde ser escrita como o livro a escreve, e o motivo valia mais do que a conta. A Eq. 4.37, Tαβ = (ρ+p)UαUβ + p ηαβ, não tinha grafia neste programa: um monômio só aceitava coeficiente racional. Com um número funcionava; com um símbolo, não.

tensor T^{\mu\nu} := 3 U^{\mu} U^{\nu}            ->  ok
tensor T^{\mu\nu} := rho U^{\mu} U^{\nu}          ->  unknown tensor head `rho`

E a saída que o programa oferecia não existia. Declarar o escalar como tensor de rank 0 era recusado, e a recusa mandava usar um apelido; o apelido era recusado onde a mensagem mandava usá-lo. Três mensagens, nenhuma errada por si, e um laço fechado.

O que foi feito

O coeficiente escalar passou a existir, entre parênteses:

eval (rho + p) U[a] U[b] + (p) g[a,b]
tensor T^{\mu\nu} := (rho + p) U^{\mu} U^{\nu} + (p) g^{\mu\nu}

Ele aceita qualquer expressão escalar — apelido, função conhecida, fração —, multiplica o termo inteiro (contrações incluídas), e é aplicado depois da avaliação: (rho) U[a] U[a] é −ρ, não ρ, porque U·U = −1.

Onde ele NÃO vale, e por quê

O escalar viaja ao lado do monômio, não dentro dele. O coeficiente de um monômio é um racional de máquina de propósito: ele entra no Eq/Hash e na ordenação de Butler–Portugal, e trocá-lo por expressão simbólica seria mudar o tipo central do núcleo, com consequências em simplify, solve e na canonicalização.

Então quem avalia componentes multiplica a grade pelo escalar, e o lado abstrato recusa — dizendo onde a grafia vale, que é o que faltava nas três mensagens antigas:

simplify (rho + p) T[a,b]
error: um coeficiente escalar entre parenteses -- `(rho + p) U^{\mu} U^{\nu}` --
       so' vale onde ha COMPONENTES para multiplicar: `eval` e o lado direito de
       `tensor NOME^{...} := ...`. No lado abstrato (`simplify`, `solve`, `canon`)
       um simbolo solto nao tem significado sem um head de rank 0 que o declare
       (`head NOME : on M`)

As outras duas mensagens do laço passaram a apontar para a saída que agora existe. Um nome solto em posição de fator sugere os parênteses; a recusa do rank 0 diz as duas coisas — como declarar o escalar e como usá-lo:

tensor T^{\mu\nu} := rho U^{\mu} U^{\nu}
error: unknown tensor head `rho` -- se `rho` era para ser um coeficiente
       ESCALAR, ele vai entre parenteses: `(rho) T^{\mu\nu}`

tensor E : on mink { [] = rho + p }
error: `E` teria rank 0 (um escalar). Um escalar com valor se declara como
       apelido (`E := EXPR`), e entra numa expressao tensorial como
       COEFICIENTE, entre parenteses: `(E) T^{\mu\nu}`

A dica dos parênteses só aparece quando o fator não tem índices. Quem escreveu Q[a,b] quis um tensor, e sugerir um coeficiente ali seria conselho errado — tem teste próprio dizendo isso.