RustedSciThe 0.4.25

Rust framework for symbolic and numerical computing:BVP ( Newton-Raphson frozen/damped/with collocations ), IVP( BDF, Radau, Backward Euler, LSODE, LSODA, RK45, DoPri), nonlinear equations ( Levenberg, Gavin) and more
# Руководство пользователя ShootingBVP

ShootingBVP решает краевую задачу многократным интегрированием задачи Коши и
корректировкой одного неизвестного начального значения методом секущих.
Поддерживаемый символьный маршрут использует Lambdify-инфраструктуру крейта и
фронтенды `ExprLegacy` и `AtomViewNative`.

## Когда использовать метод стрельбы

Текущая реализация предназначена для **одного скалярного ОДУ второго порядка**,
представленного двумя компонентами состояния `[y, y']`. Это разумный выбор для
отдельного уравнения; концептуально метод подходит и для очень малых связанных
систем, если такая система будет явно поддержана API. Сейчас API требует ровно
две переменные состояния и два уравнения и не реализует связанные векторные
системы второго порядка.

Метод стрельбы не является универсальным методом для больших систем. Каждая
итерация секущих требует полного решения задачи Коши, а чувствительность
траектории к неизвестному начальному значению может сделать сходимость хрупкой.
Для больших связанных систем, сложных пограничных слоёв или неустойчивых задач
Коши выбирайте коллокационный BVP-солвер, например BVP_Damp или BVP_sci. Нет
универсально самого быстрого солвера: выбор зависит от структуры задачи, а
результат следует проверять по точному решению или независимому солверу.

## Типизированный builder API

Builder явно задаёт левые и правые граничные условия и выбирает IVP-солвер через
тип `SolverType`. Пример решает `y'' = y`, `y(0)=0`, `y(1)=sinh(1)`; точное
решение равно `sinh(x)`:

```rust
use RustedSciThe::numerical::ODE_api2::{NonStiffMethod, SolverType};
use RustedSciThe::numerical::ShootingBVP::Shooting_simple::{
    BoundaryCondition, BoundaryConditionType,
};
use RustedSciThe::numerical::ShootingBVP::{ShootingSymbolicOptions, shooting_bvp};
use RustedSciThe::numerical::SolverTelemetryMode;
use RustedSciThe::symbolic::symbolic_engine::Expr;

let problem = shooting_bvp(
    vec![Expr::parse_expression("dy"), Expr::parse_expression("y")],
    vec!["y".into(), "dy".into()],
    "x",
)
.interval(0.0, 1.0)
.boundary_conditions(
    BoundaryCondition { value: 0.0, bc_type: BoundaryConditionType::Dirichlet },
    BoundaryCondition {
        value: 1.0_f64.sinh(),
        bc_type: BoundaryConditionType::Dirichlet,
    },
)
.initial_guess(0.8)
.tolerance(1e-8)
.max_iterations(30)
.step_size(0.002)
.ivp_solver(SolverType::NonStiff(NonStiffMethod::Rk45))
.symbolic_options(ShootingSymbolicOptions::default())
.build()?;

let report = problem.solve(SolverTelemetryMode::Detailed)?;
let solution = report.solve.solution;
assert!((solution.bound_values[0] - 1.0_f64.sinh()).abs() < 1e-5);
# Ok::<(), Box<dyn std::error::Error>>(())
```

Полностью прокомментированный запускаемый пример находится в
`examples/shooting_bvp_builder_guide.rs`:

```text
cargo run --example shooting_bvp_builder_guide
```

## Телеметрия

Метод builder `solve` принимает общий `SolverTelemetryMode`: `Off` ничего не
собирает, `Counters` считает дискретные события без чтения часов, `Timings`
измеряет длительности без обновления счётчиков, `Detailed` собирает оба вида
данных. В `ShootingTelemetry.mode` сохраняется выбранная политика, поэтому
нулевые поля неактивного канала нельзя спутать с измеренным нулём.

Порядок компонент состояния — `[y, y']`; поэтому система уравнений имеет вид
`[y', f(x,y,y')]`. На каждом конце задаётся ровно одно скалярное условие:
`Dirichlet` ограничивает `y`, а `Neumann` — `y'`. Поддерживаются смешанные
условия, например `y(a)=alpha` и `y'(b)=beta`.

Параметр shooting `tolerance` ограничивает внешнюю невязку на границе, а не
точность каждой IVP-траектории. Настраивайте точность самого выбранного
IVP-солвера отдельно: малая невязка секущих не компенсирует погрешность,
полученную при слишком грубом интегрировании задачи Коши.

## IVP-солвер и символьный фронтенд

Типизированный builder принимает `SolverType`: в том числе методы для нежёстких
задач, BDF, Radau, Backward Euler и LSODE2, если выбранный метод доступен в
конфигурации крейта. По умолчанию используется RK45. Специфичные для метода
параметры передаются через `solver_parameter(name, SolverParam::...)`; имена и
типы параметров нужно сверять с API выбранного IVP-солвера. Например, native
адаптер BDF принимает `rtol`, `atol` и `max_step`.

Выбор символьного фронтенда не зависит от выбора IVP-солвера:

```rust
use RustedSciThe::numerical::Nonlinear_systems::symbolic::SymbolicLambdifyFrontend;

let options = ShootingSymbolicOptions {
    frontend: SymbolicLambdifyFrontend::AtomViewNative,
    ..ShootingSymbolicOptions::default()
};
```

По умолчанию выбран `ExprLegacy`, который может быть удобен для малых выражений.
`AtomViewNative` оставляет символьные операции на представлении Atom. Оба пути
используют Lambdify; AOT пока не поддерживается. Нельзя считать один фронтенд
безусловно быстрее: сравнивайте их на одной задаче и с одинаковыми настройками
IVP-солвера.

## Результат, телеметрия и логгирование

`solve(true)` возвращает траекторию, выбранный фронтенд, отчёт символьной
подготовки, её wall time и opt-in численную телеметрию. Счётчики включают число
итераций секущих, вычислений невязки и вызовов IVP-солвера. Тайминги разделяют
фазу секущих, интегрирования для невязок, финальное построение траектории и
полное решение. Некоторые области времени вложены друг в друга, поэтому их
нельзя суммировать как независимые затраты.

Телеметрия включается одной опцией: если она не нужна, используйте
`solve(false)`. Логгирование по умолчанию выключено. Его можно включить методом
`.logging_level(SolverLogLevel::Info)`; общий logging layer записывает сообщения
в файл с временной меткой. Ошибка создания файла возвращается как typed error.
Численные ошибки также типизированы (`ShootingBvpError`), а после неудачного
solve прежняя траектория очищается, чтобы её нельзя было принять за результат
текущего запуска.

Builder пока выполняет символьную подготовку заново при каждом вызове `solve`;
prepared continuation-интерфейса здесь ещё нет. Для серий задач с изменяемыми
параметрами используйте солвер с явным lifecycle подготовки/rebind, пока такая
возможность не появится в ShootingBVP.

## Независимая проверка корректности

Debug-тест `shooting_matches_independent_damped_bvp_on_common_mesh` сравнивает
ShootingBVP с BVP_Damp на одной задаче гармонического осциллятора:
`y'' + y = 0`, `y(0)=0`, `y(pi/2)=1`. Поскольку решатели выбирают разные сетки,
обе траектории линейно интерполируются на 81 общую координату; максимальное
покомпонентное различие должно быть меньше `2e-3`. Каждый решатель отдельно
сверяется с точным решением `y=sin(x)`, `y'=cos(x)`, поэтому совпадения двух
одинаково неточных траекторий недостаточно для прохождения проверки. Это gate
корректности, а не сравнение производительности; количество узлов и специфичные
для каждого алгоритма счётчики итераций между собой не сравниваются.

## Совместимый API

`BVPShooting` и прежний интерфейс граничных условий на `HashMap` сохранены для
совместимости. В новом коде предпочтителен `shooting_bvp(...)`: он проверяет
обязательные поля и предоставляет типизированные условия на концах отрезка и
выбор IVP-солвера, не заставляя пользователя собирать legacy-карту вручную.