Численное ядро

Параметры Риккати

Уравнение Узаделя решается в параметризации Риккати: на каждой частоте/энергии — своя краевая задача (BVP) для 16 компонент.

Riccati (Core/Model/Kernels/Riccati) хранит все 16 компонент (gam11Egamt22E и их производные dgam11Edgamt22E) как трёхмерные тензоры формы ``(eN × zN × stepsN)`` — энергия/частота, координата, шаг самосогласования. Хранение именно тензором на все шаги сразу (а не только последний) сделано специально: это даёт OrderParameterHistory и возможность посмотреть/отладить сходимость по шагам постфактум, а не только финальный результат.

Метод: getRiccatiIndices() — возвращает struct, отображающий мнемонические имена компонент (GAM11, GAMT12 и т.д.) на номера строк в векторе решения, который возвращает bvp4c. Смысл — солверы обращаются к решению по имени (idx.GAM12), а не по «магическому числу» 9, что и читаемее, и не ломается, если порядок компонент в ОДУ когда-нибудь изменится.

Функции Грина

Core/Model/Kernels/GreenFunctions, общий предок — абстрактный GreenBase: хранит 16 компонент G11EG44E в том же соглашении (eN × zN), что и Riccati (компоненты объявлены protected — наследники и процедуры обязаны читать их через методы ниже, не напрямую).

Методы базового класса:

Метод

Зачем

GetGreenMatrix(eIdx, zIdx)

собрать 4×4 матрицу Грина в конкретном узле сетки. Это основной способ читать функцию Грина откуда угодно, не обращаясь к 16 полям по отдельности

GetInterpPart(zIdx, comp, E_mesh)

сплайн-интерполяция одной компоненты по энергии при фиксированной координате. Нужна, когда функцию Грина требуется вычислить не в узле сетки — например, в проводимости energии сдвигаются на ±ω/2 и почти никогда не попадают ровно в исходную сетку

GetSecondDerivativeZ(eIdx, zIdx, zStep)

вторая производная 4×4 матрицы по координате (центральная разность, односторонняя схема на границах). Нужна только для свободной энергии — в её формуле есть слагаемое со второй производной функции Грина по z

Три конкретных представления, каждое — со своим способом вычислить те же 16 компонент:

  • RetardedGreenFunction — метод CalculateGreenByRiccati(riccatiTensor, stepIdx) строит запаздывающую функцию Грина из параметров Риккати на заданном шаге самосогласования (обычно последнем). Дополнительно методы FormAnomal() / UpdateAnomal() считают аномальные (синглетную и триплетные) компоненты — они не нужны для плотности состояний, но нужны как физическая интерпретация сверхпроводящих корреляций; метод GetDos(zIdx) — плотность состояний по всем энергиям при фиксированной координате, готовая свёртка через GetGreenMatrix + trace, чтобы не дублировать формулу в вызывающем коде.

  • AdvancedGreenFunction — строится из запаздывающей методом CalculateAdvancedGreen: G^A = −σ₃(G^R)†σ₃. Отдельный класс, а не просто формула внутри вызывающего кода, — потому что опережающая функция Грина сама по себе нужна в нескольких местах (в частности, в проводимости) и физически имеет тот же интерфейс (GetGreenMatrix и т.д.), что и запаздывающая.

  • KeldyshGreenFunction — из запаздывающей и опережающей, метод CalculateKeldyshGreen: G^K = (G^R − G^A)·tanh(βω/2). Нужна только для проводимости (формализм Келдыша, неравновесная величина).

Проводимость

Conductivity (Core/Model/Kernels/Conductivity) — простой контейнер результата без логики: поле ConductFull (zN × oN, комплексная). Сама формула (интеграл по энергии от комбинации запаздывающей/опережающей/ келдышевской функций Грина на энергиях, сдвинутых на ±ω/2) живёт в процедуре SFIEnergyBasedFindConductivity (см. ниже), не в этом классе — класс тут исключительно как типизированное хранилище результата.

Решатели (Core/Solvers)

Для каждого представления — набор функций для bvp4c:

Функция

Зачем

SCFIEnergyBasedODE / SCFIMatsubaraODE

правая часть уравнения Узаделя в параметризации Риккати — то, что bvp4c интегрирует по координате

SCFIEnergyBasedBoundary / SCFIEnergyBasedBoundaryTripple

граничные условия: первая — для структуры S-FI (один контакт), вторая — для FI-S-FI (два контакта, оба с ферромагнитным изолятором). Выбор между ними делает пайплайн по InitialConditions.IsTripleLayer, не сам солвер

SCFIEnergyBasedInitialGuess / аналог для Matsubara

начальное приближение для bvp4c на первом шаге самосогласования (на последующих шагах используется решение предыдущего шага — так быстрее сходится)

SCFIEnergyBasedForm_Delta / аналог для Matsubara

формула щели Δ(z) из параметров Риккати — используется внутри процедуры пересчёта щели (см. ниже)

Главный узел — процедура самосогласованного цикла (SFIEnergyBasedSelfConsistencyLoopProcedure / SFIMatsubaraSelfConsistencyLoopProcedure, у каждой есть _Parfor-версия для параллельного счёта по энергиям/частотам). На каждом шаге:

  1. решает краевую задачу bvp4c для каждой энергии/частоты (независимо друг от друга — отсюда и возможность parfor);

  2. собирает результаты в тензор Riccati, строит по нему функцию Грина (RetardedGreenFunction.CalculateGreenByRiccati);

  3. пересчитывает Δ(z) — функция SFIEnergyBasedComputeSelfConsistentGap(riccatiTensor, calculation, stepIdx), отдельная от солвера ОДУ, потому что формула щели — интеграл по энергии от аномальной части функции Грина, а не часть самого дифференциального уравнения;

  4. проверяет сходимость: относительное изменение Δ(z) между шагами меньше OrderParameterTolerance → цикл останавливается, иначе — следующий шаг (до SelfConsistencySteps).

Пайплайны (Core/Pipelines)

RunSFIEnergyBasedPipeline / RunSFIMatsubaraPipeline — верхний уровень, вызывается напрямую или (обычно) через Скриптовый слой (Core/Scripting)/CalculationRunner:

  1. настройка логгера (Logger.Setup) — чтобы каждый расчёт имел свой лог-файл, а не общий поток вывода в консоль;

  2. создание CalculatedPhysicalProperties, если ещё нет;

  3. запуск таймера (Timer) — для CalculationTime в результате;

  4. самосогласованный цикл (последовательный или parfor, в зависимости от переданного флага);

  5. физические процедуры (см. ниже) — список настраиваемый через необязательный аргумент propertyProcedures: если не передан, используется весь стандартный набор (обратная совместимость с кодом, который вызывает пайплайн напрямую, без скриптового слоя);

  6. остановка таймера, запись CalculationTime.

Каждый шаг физических процедур обёрнут в свой try/catch — одна упавшая процедура (например, Conductivity без заданной сетки частот) не мешает досчитать и сохранить остальные.

Физические процедуры

Core/PhysicalPropertiesProcedures/SFI/EnergyBased — каждая процедура принимает и возвращает calculation (единообразная сигнатура специально для того, чтобы их можно было выстроить в список и вызывать в цикле, как это делает пайплайн и скриптовый слой), дописывая в CalculatedPhysicalProperties свой результат и выставляя соответствующий флаг в PhysicsPipelineEndState:

Процедура

Что считает

Откуда берёт данные

SFIEnergyBasedFindGreenFunctions

гарантирует наличие запаздывающей функции Грина

обычно уже посчитана внутри самосогласованного цикла — процедура просто проверяет IsGreenReady и досчитывает, если почему-то нет

SFIEnergyBasedFindDensityofStates

полная плотность состояний N(z,ε)

trace нормальной части функции Грина в каждом узле сетки

SFIEnergyBasedFindSpinDoS

спин-разрешённая N↑/N↓(z,ε)

то же, спроецированное на матрицу Паули σ₃

SFIEnergyBasedFindMagnetization

намагниченность M(z)

интеграл по энергии от trace(σ₃·g(z,ε))

SFIEnergyBasedFindFreeEnergy

свободная энергия (σ-модель)

интеграл по z и по энергии от функции Грина и её второй производной (GetSecondDerivativeZ)

SFIEnergyBasedFindConductivity

комплексная проводимость σ(z,ω)

запаздывающая + опережающая + келдышевская функции Грина на энергиях ±ω/2; требует заданной сетки частот, иначе тихо пропускается

Именно этот список процедур виден и настраивается через cfg.Procedures в скриптовом слое — подробности в Шаг 3. Какие величины считать.