Мне нужно получить такое же решение, как представл...

Created on: September 9, 2026

Answered using GPT-5.6 Thinking by Chat01

Question

Гаусс-Бонне_new.nb
2207.03944v2.pdf

Мне нужно получить такое же решение, как представлено в этой статье. Я решаю систему уравнений (24), (25) и (27) численно в wolfram с граничными условиями (3),(28) и (32) методом стрельбы с параметром стрельбы \phi_S, но почему-то функция shoot выдает FAiled. Проверь, пожалуйста, весь код, найди все ошибки и исправь их. Дальше строчки с функцией scanResidual НЕ СМОТРИ И НЕ ПРОВЕРЯЙ, это черновики, не имеющие отношения к основному коду.

Thought

Resource uri: /response/turn1 Showing 734 of 734 lines. Pagination: has_more=true, next_cursor="/response/turn1"

undefined

Thought

Resource uri: /response/turn2 Showing 105 of 105 lines.

undefined

Thought

Resource uri: /response/turn3 Showing 338 of 338 lines. Response metadata: surface=conversation, mode=pages Pagination: has_more=false, end_line=328, total_lines=328

undefined

Thought

Resource uri: /response/turn4 Showing 30 of 30 lines. Response metadata: surface=conversation Pagination: has_more=false, end_line=2067, total_lines=2067

undefined

Thought

Computed shooting parameter checks and created corrected Gauss-Bonnet code

Worked for 9m 5s

Answer

Да. Я проверил основной код до строки ClearAll[scanResidual]; сам scanResidual и всё, что идёт после него, я не анализировал, как вы просили.

Главное: проблема не одна. В коде есть несколько независимых ошибок, и две из них сами по себе достаточны, чтобы shoot возвращал $Failed.

Что ломает код

  1. Самая серьёзная программная ошибка — смешаны функции и их численные значения.

Например, у вас определено примерно так:

wl
nuPrimeFun[r_, phi_, phip_, lam_] := ... Exp[lam[r]] phip[r]^2 ...

а вызывается:

wl
nuPrimeFun[r, phi[r], F[r], lam[r]]

После подстановки Mathematica фактически получает конструкции вида

wl
Exp[lam[r][r]] F[r][r]^2 phi[r][r]

То есть аргумент lam_ уже равен значению lam[r], но затем вы второй раз применяете к нему [r].

Эта ошибка была сразу в нескольких местах:

wl
Aexpr nuPrimeFun lambdaPrimeFun C33 rhsVals

Именно поэтому правая часть системы перестаёт быть численной для NDSolve.

В исправленной версии везде разделены численные аргументы:

wl
Aexpr[rr_, ph_, pp_, la_] := ... Exp[la] ph pp

а не la[rr], ph[rr], pp[rr].


  1. shoot[0.2] для ваших параметров вообще не должен работать.

В статье ϕS\phi_S — это именно параметр стрельбы на горизонте, который подбирается так, чтобы на бесконечности получилось ϕv\phi\to v. Авторы прямо это пишут. (2207.03944v2.pdf)

То есть

wl
phiS = v

ставить нельзя.

Для ваших параметров

wl
ell = 3; mu = 0.1; h = 0.5; v = 0.2;

режим как раз соответствует фиолетовой кривой Fig. 3, μ=0.1,=3,v=0.2\mu=0.1,\ell=3,v=0.2. (2207.03944v2.pdf)

В этом режиме поле около горизонта почти равно нулю, а не v=0.2v=0.2.

Я отдельно подставил ваши исходные значения rS=1.01, ell=3, phiS=0.2 в (30)+(32). Для phiS=0.2 имеем V=V,ϕ=0V=V_{,\phi}=0, и уравнение (32) даёт для ϕS\phi'_S

ϕS0.03507±1.71454i.\phi'_S \simeq 0.03507\pm1.71454\,i .

Реального ϕS\phi'_S вообще нет. Поэтому ваш

wl
FindRoot[..., {x, 0.1}]

и выдаёт FindRoot::lstol. Это не проблема начального приближения 0.1: при phiS=0.2 искомого вещественного корня нет.

По независимой численной проверке исправленной системы для параметров Fig. 3 и rmax=50 физический параметр стрельбы находится примерно около

ϕS6.4×109,\boxed{\phi_S \approx 6.4\times10^{-9}},

а не около 0.2 и тем более не около 0.87.


  1. phiPrimeS нельзя надёжно определять одним FindRoot[{x,0.1}].

Уравнение (32), совместно с (30), является алгебраическим по ϕS\phi'_S. В зависимости от ϕS\phi_S оно может иметь:

  • два вещественных корня;
  • один предельный корень;
  • вообще не иметь вещественных корней.

Причём нужно ещё выбрать физическую ветвь с

b1>0.b_1>0.

В статье именно (30) задаёт b1b_1, а (32) — граничное условие для производной поля. (2207.03944v2.pdf) (2207.03944v2.pdf)

Я заменил этот FindRoot на NSolve[..., Reals], отбрасываю корни с b1<=0 и выбираю физическую ветвь, непрерывно связанную с приближением

wl
24 ell^2 phiS/rS^3 + rS Vp[phiS]

  1. rS = 1.01 неверно, если вы хотите воспроизвести графики статьи.

Авторы переходят к безразмерной координате

rr/rS,r\to r/r_S,

следовательно, после этого горизонт находится в

rS=1.r_S=1.

(2207.03944v2.pdf)

У вас одновременно стояло

wl
rS = 1.01; eps = 0.01;

а затем интегрирование начиналось с

wl
rS + eps

то есть фактически с 1.02.

Нужно:

wl
rS = 1; eps = 1/100; r0 = rS + eps; (* 1.01 *)

eps и есть отступ от горизонта.


  1. У вас закомментирована обязательная проверка b1 > 0.

Было:

wl
(* If[bb <= 0, Return[$Failed]]; *)

Но затем используется

wl
lam[r0] == -Log[bb eps]

Если bb<=0, решение немедленно становится комплексным. Проверку нужно вернуть.


  1. Quiet@Check[..., $Failed] скрывает настоящую причину ошибки.

Конструкция

wl
Quiet @ Check[ NDSolve[...], $Failed ]

очень неудобна для такого расчёта: Check может превратить вычисление в $Failed при сообщении от NDSolve, а Quiet одновременно скрывает это сообщение.

Поэтому вы видите только $Failed и не видите, что произошло внутри.

Я это убрал: теперь NDSolveValue показывает настоящие диагностические сообщения, а $Failed возвращается только если действительно не получилось получить четыре InterpolatingFunction.


  1. MachinePrecision здесь недостаточно надёжен.

У вас:

wl
mu = 0.1; h = 0.5; rS = 1.01;

то есть машинные числа, а параметр стрельбы для рассматриваемого решения порядка 10910^{-9}. Кроме того, наружная стрельба является очень чувствительной separatrix-задачей: надо подавить растущую асимптотическую моду.

И сам Mathematica у вас сообщает:

text
You may need more than MachinePrecision digits ...

Я перевёл параметры в точные числа:

wl
mu = 1/10; v = 1/5; h = mu/v;

и использовал

wl
WorkingPrecision -> 50 AccuracyGoal -> 28 PrecisionGoal -> 22

  1. В findPhiS у вас неправильное уравнение.

Вы определяете

wl
residual[phiS] = phi[rmax] - v

но затем ищете

wl
residual[phiS] == 0.1

Для условия (3)

ϕ=v\phi_\infty=v

должно быть строго

wl
residual[phiS] == 0

Условие ϕ=v\phi_\infty=v дано в статье в (3), а метод стрельбы именно подбирает ϕS\phi_S, чтобы его выполнить. (2207.03944v2.pdf) (2207.03944v2.pdf)

Кроме того, стартовать FindRoot с

wl
phi0 = 0.0

для этой задачи неудобно. Для ваших параметров корень порядка 10910^{-9}, поэтому я использовал две стартовые точки:

wl
{x, 6*10^-9, 7*10^-9}

  1. Ошибки есть и в ваших тестовых Plot до scanResidual.

Вот это неверно:

wl
Plot[nu /. shoot[0.87], ...]

Во-первых, надо вычислять nu[rr], а не символ nu. Во-вторых, 0.87 совершенно не является физическим phiS для набора v=0.2.

И это:

wl
Plot[lam[rr] /. shoot, ...]

тоже неверно: shoot — функция, а не список правил. Именно поэтому Mathematica пишет:

text
{shoot} is neither a list of replacement rules ...

В исправленной версии сначала вычисляется

wl
sol = shoot[phiSsol];

а затем используются непосредственно InterpolatingFunction:

wl
phiIF = sol[[1]]; nuIF = sol[[3]]; lamIF = sol[[4]];

  1. Для eνe^\nu нужна дополнительная нормировка.

Граничное условие горизонта фиксирует

eν=a1(rrS)+,e^\nu=a_1(r-r_S)+\ldots,

но константа a1a_1 связана с произвольной нормировкой времени. В статье условие (28) задаёт только исчезновение eνe^\nu и eλe^{-\lambda} на горизонте. (2207.03944v2.pdf)

Поэтому выбор

wl
nu[r0] == Log[eps]

допустим для интегрирования, но перед сравнением с Fig. 4 надо сделать постоянный сдвиг ν\nu, чтобы метрика была асимптотически Минковской.

Я добавил:

wl
nuShift = -(nuIF[rmax] + lamIF[rmax]); enu[r_] := Exp[nuIF[r] + nuShift];

Сами уравнения (24), (25), (26), (27)

Знаки и коэффициенты в вашей реализации (24) и (25) после решения относительно lambda' и nu' у вас в основном были правильными. Аналогично разложение (26),(27) в rhsVals по ν\nu'' и ϕ\phi'' математически сделано правильно — там основная ошибка была именно в передаче значений как функций.

И использование (26) здесь не противоречит вашему желанию решать (24),(25),(27): авторы отмечают, что из четырёх уравнений независимы только три из-за тождеств Бианки. (2207.03944v2.pdf) Уравнение (26) можно использовать алгебраически для исключения ν\nu'' из (27).

Исправленный код

Я собрал чистую версию всего основного расчёта: потенциал, (30), (32), правильные (24),(25), исключение вторых производных, shoot, residual, findPhiS и построение трёх графиков. scanResidual туда намеренно не включал.

[Скачать исправленный Wolfram Language код]

Для вашего набора μ=0.1,=3,v=0.2\mu=0.1,\ell=3,v=0.2 контрольные значения после исправления должны быть примерно такими:

text
phiS ~ 6.4*10^-9 phi[50] ~ 0.2 phi[12]/v ~ 0.95

Последнее хорошо соответствует фиолетовой кривой Fig. 3: в статье для неё как раз указано μ=0.1,=3,v=0.2\mu=0.1,\ell=3,v=0.2. (2207.03944v2.pdf)

Самая важная последовательность проверки сейчас такая: сначала выполните файл целиком, затем отдельно посмотрите phiPrimeS[0.2] — он корректно должен сообщить, что физической вещественной ветви нет; после этого phiSsol = findPhiS[] должен найти малое значение порядка 10910^{-9}, и уже shoot[phiSsol] должен дать InterpolatingFunction, а не $Failed.

Share this Q&A