Convergence Tuning Guide (Python + YAML)¶
Este guia foca no runtime suportado: Python + YAML (pulsim-v1).
⚠️ Primeiro passo — escolha um preset¶
Antes de tunar campo a campo, escolha um preset numérico em
numerical-configuration.md. 95% dos
casos de não-convergência se resolvem trocando Preset.Auto por
Preset.Robust (que liga TRBDF2 + stiffness + 12 retries + Armijo
line search + homotopy DC):
opts = ps.SimulationOptions.from_preset(ps.Preset.Robust, 1e-6, 1e-3)
simulation:
preset: robust
tstop: 1e-3
dt: 1e-6
O resto deste guia é para os casos restantes que precisam de tuning fino. Se o preset resolver, não passe daqui.
Sintomas comuns¶
- Falha no ponto de operação DC (
dc_operating_point). - Muitos
timestep_rejectionsno transiente. - Queda para fallback linear com frequência alta.
- Passos muito pequenos e simulação lenta.
Convergence aids automáticas (ligadas por default)¶
Pulsim ship com quatro aids automáticas que disparam em casos
difíceis sem o usuário precisar configurar — todas chegaram com o
release simplify-and-harden-numerical-surface:
| Aid | Quando dispara | Sintoma de que ajudou |
|---|---|---|
| Armijo line search (Newton) | Sempre que o full step Newton aumenta o resíduo | result.newton_result.telemetry.line_search_backtracks > 0 |
| Coalescência de eventos simultâneos (PWL) | ≥ 2 switches comutam dentro da tolerância de bisection | result.backend_telemetry.simultaneous_event_groups > 0 |
| Iterative refinement (KLU/SparseLU) | Resíduo pós-back-solve > 10·ε_machine | result.linear_solver_telemetry.linear_refinement_steps > 0 |
| Homotopy continuation (DC OP) | Direct → Source → Gmin → PseudoTransient all fail | result.dc_result.strategy_used == DCStrategy.Homotopy |
Veja Numerical Configuration para detalhes e tuning de cada uma.
Checklist rápido¶
- Pegue o preset certo (
Preset.Robusté o ponto de partida). - Garanta caminho DC para o terra (evite nós flutuantes).
- Use
simulation.solver.orderefallback_orderexplícitos só se precisar mais que o auto-selector. - Em circuitos stiff, o preset Robust já escolhe
integrator: trbdf2automaticamente. Override pararosenbrockwsó se TRBDF2 falhar. Preset.Fastquando o circuito é só switching.
Verificar backends compilados¶
No Python:
import pulsim as ps
print(ps.backend_capabilities())
# {'klu': True, 'hypre_amg': True/False, 'sundials': True/False}
Observação: sundials=True indica apenas suporte compilado opcional. No caminho
suportado de transiente, use o core nativo com simulation.step_mode
(fixed|variable), sem seleção de backend legado.
Exemplo de configuração robusta¶
schema: pulsim-v1
version: 1
simulation:
tstart: 0.0
tstop: 2e-3
dt: 1e-6
step_mode: variable
dt_min: 1e-10
dt_max: 5e-5
adaptive_timestep: true # override avançado
integrator: trbdf2
solver:
order: [klu, gmres]
fallback_order: [sparselu]
allow_fallback: true
auto_select: true
size_threshold: 400
nnz_threshold: 2500
diag_min_threshold: 1e-12
iterative:
max_iterations: 300
tolerance: 1e-8
restart: 40
preconditioner: ilut
ilut_drop_tolerance: 1e-3
ilut_fill_factor: 10
enable_scaling: true
scaling_floor: 1e-12
newton:
max_iterations: 60
enable_limiting: true
max_voltage_step: 2.0
max_current_step: 5.0
Ajustes por cenário¶
Buck/boost com chaveamento rápido¶
integrator: trbdf2dtinicial pequeno (ordem de 1/50 a 1/200 do período de comutação)enable_events: true
Malha grande com muitos passivos¶
order: [gmres, klu]ou[klu, gmres](teste as duas)- ILUT ligado
- aumente
iterative.max_iterations
Problema quase singular¶
- aumente
diag_min_threshold - reduza
max_voltage_step - aumente
gmin_fallbackemax_step_retries
Observabilidade para diagnóstico¶
No resultado transiente, acompanhe:
result.newton_iterations_totalresult.timestep_rejectionsresult.linear_solver_telemetry.total_fallbacksresult.fallback_trace
Esses campos são essenciais para comparar tuning entre cenários e evitar regressão.
Estratégia de validação¶
- Ajuste em circuito pequeno de referência.
- Replique no benchmark matrix.
- Confirme em
ngspicee depoisLTspice. - Execute stress tiers A/B/C antes de promover configuração.