# -*- coding: utf-8 -*-
"""
Module introducing the class SystemState bundles the synchrotron
and rf parameters and is the entry point for fixed parameterset
ALBuMS computations.
"""
from __future__ import annotations
from copy import deepcopy
from typing import TYPE_CHECKING
from albums.equilibrium import Equilibrium, EquilibriumSolver
from albums.flow import Flow, Result
from albums.options import EquilibriumOptions, TheoryOptions
if TYPE_CHECKING: # pragma: no cover - hints only
from mbtrack2 import CavityResonator, Synchrotron
[docs]class SystemState:
"""
This class bundles the synchrotron and rf parameters and is the
entry point for fixed parameterset ALBuMS computations.
Use run to drive a Flow, composed of:
- a chosen equilibrium solver (Bosch, Venturini or Alves).
- paired with a chosen subset of instability theories (see albums.theories).
See albums.flow.DEFAULT_FLOWS for the prebuilt Bosch/Venturini/Alves
flows, or build a custom Flow.
Parameters
----------
ring : Synchrotron object
Ring parameters.
cavity_list : list of CavityResonator objects
At least two cavities: the main cavity in position 0, followed by one or
more harmonic cavities.
Methods
-------
run(flow, eq_opts, theory_opts)
Solve the equilibrium and evaluate a flow's theories.
run_equilibrium(flow, eq_opts)
Solve only the beam equilibrium.
References
----------
[1] : Bosch, R. A., K. J. Kleman, and J. J. Bisognano. "Robinson
instabilities with a higher-harmonic cavity." Physical Review Special
Topics-Accelerators and Beams 4.7 (2001): 074401.
[2] : Bosch, R. A., and C. S. Hsue. "Suppression of longitudinal
coupled-bunch instabilities by a passive higher harmonic cavity."
Proceedings of International Conference on Particle Accelerators. IEEE, 1993.
[3] : Gamelin, A., Yamamoto, N. (2021). Equilibrium bunch density
distribution with multiple active and passive RF cavities.
IPAC'21 (MOPAB069).
[4] : Venturini, M. (2018). Passive higher-harmonic rf cavities with general
settings and multibunch instabilities in electron storage rings.
Physical Review Accelerators and Beams, 21(11), 114404.
[5] : Alves, Murilo B., and Fernando H. de Sá. "Equilibrium of longitudinal
bunch distributions in electron storage rings with arbitrary impedance
sources and generic filling patterns." Physical Review Accelerators and
Beams 26.9 (2023): 094402.
[6] : de Sá, F., & Alves, M. (2023). pycolleff and cppcolleff: modules for
impedance analysis and wake-field induced instabilities evaluation.
(Version 0.1.0) [Computer software]. https://doi.org/10.5281/zenodo.7974571
[7] : He, Tianlong. "Novel perturbation method for judging the stability of
the equilibrium solution in the presence of passive harmonic cavities."
Physical Review Accelerators and Beams 25.9 (2022): 094402.
"""
[docs] def __init__(self, ring: Synchrotron, cavity_list: list[CavityResonator]):
if len(cavity_list) < 2:
raise ValueError(
"cavity_list must contain at least a main cavity and one harmonic "
f"cavity (got {len(cavity_list)})."
)
self.ring = ring
self.cavity_list = []
for item in cavity_list:
self.cavity_list.append(deepcopy(item))
self.n_cavity = len(cavity_list)
def __repr__(self) -> str:
ring_name = getattr(self.ring, "name", None) or type(self.ring).__name__
return f"SystemState(ring={ring_name!r}, n_cavity={self.n_cavity})"
[docs] def _solve(
self, solver: EquilibriumSolver, eq_opts: EquilibriumOptions
) -> Equilibrium:
if eq_opts.I0 is None:
raise ValueError(
"EquilibriumOptions.I0 is not set. Set the beam current before "
"solving, e.g. EquilibriumOptions(I0=...). Current-sweeping scans "
"fill it per grid point and may leave it None here."
)
return solver.solve(self.ring, self.cavity_list, eq_opts)
[docs] def run_equilibrium(self, flow: Flow, eq_opts: EquilibriumOptions) -> Result:
"""
Solve only the beam equilibrium of a flow (no instability theories) and
return a Result carrying bunch length, R-factor and xi.
Parameters
----------
flow : Flow
The (equilibrium solver, theories) pipeline; only its equilibrium
solver is used here.
eq_opts : EquilibriumOptions
The beam current, integration boundary and every solver option.
Returns
-------
Result
Structured result with theories={} (no instability theory
evaluated).
"""
flow.validate()
eq = self._solve(flow.equilibrium, eq_opts)
return Result(
converged=bool(eq.converged),
equilibrium=eq,
theories={},
Touschek=eq.Touschek,
xi=eq.xi,
)
[docs] def run(
self,
flow: Flow,
eq_opts: EquilibriumOptions,
theory_opts: TheoryOptions = TheoryOptions(),
) -> Result:
"""
Run a Flow: solve the beam equilibrium with the flow's equilibrium
method, then evaluate each of its instability theories, returning a
structured Result.
The flow selects the equilibrium solver and the subset of theories.
Parameters
----------
flow : Flow
The (equilibrium solver, theories) pipeline. Use one of
albums.DEFAULT_FLOWS or build a custom Flow.
eq_opts : EquilibriumOptions
The beam current, integration boundary and every solver option.
theory_opts : TheoryOptions, optional
The run-time inputs shared by the theories (HOM parameters,
mode coupling).
Defaults to TheoryOptions().
Returns
-------
Result
Structured result, result.theories[name] holds each TheoryResult.
"""
flow.validate()
eq = self._solve(flow.equilibrium, eq_opts)
if not eq.converged:
return Result(
converged=False,
equilibrium=eq,
theories={},
Touschek=eq.Touschek,
xi=eq.xi,
)
theory_results = {}
for theory in flow.theories:
theory_results[theory.name] = theory.evaluate(self, eq, theory_opts)
return Result(
converged=True,
equilibrium=eq,
theories=theory_results,
Touschek=eq.Touschek,
xi=eq.xi,
)