Source code for lightwin.optimisation.design_space.helper

"""Set initial values/limits in :class:`.DesignSpaceFactory`."""

import math

import numpy as np

from lightwin.core.elements.element import Element


[docs] def same_value_as_nominal( variable: str, reference_element: Element, **kwargs, ) -> float: """Return ``variable`` value in ``reference_element``. This is generally a good initial value for optimisation. """ reference_value = reference_element.get(variable, to_numpy=False) return reference_value
[docs] def phi_s_limits( reference_element: Element, max_increase_sync_phase_in_percent: float, max_absolute_sync_phase_in_deg: float = 0.0, min_absolute_sync_phase_in_deg: float = -90.0, **kwargs, ) -> tuple[float, float]: r"""Return classic limits for the synchronous phase. Minimum is ``min_absolute_sync_phase_in_deg``, which is -90 degrees by default. Maximum is nominal synchronous phase + ``max_increase_in_percent``, or ``max_absolute_sync_phase_in_deg`` which is 0 degrees by default. Parameters ---------- reference_element : Element Element in its nominal tuning. max_increase_in_percent : float Maximum increase of the synchronous phase in percent. max_absolute_sync_phase_in_deg : float, optional Maximum absolute synchronous phase in radians. The default is 0. min_absolute_sync_phase_in_deg : float, optional Minimum absolute synchronous phase in radians. The default is :math:`-\pi / 2`. Returns ------- tuple[float, float] Lower and upper limits for the synchronous phase. """ reference_phi_s = same_value_as_nominal("phi_s", reference_element) phi_s_min = math.radians(min_absolute_sync_phase_in_deg) phi_s_max = min( math.radians(max_absolute_sync_phase_in_deg), reference_phi_s * (1.0 - 1e-2 * max_increase_sync_phase_in_percent), ) return (phi_s_min, phi_s_max)
[docs] def phi_0_limits(**kwargs) -> tuple[float, float]: r"""Return classic limits for the absolute or relative rf phase. Returns ------- tuple[float, float] Always :math:`(-2\pi, 2\pi)`. """ return (-2.0 * math.pi, 2.0 * math.pi)
[docs] def k_e_limits( reference_element: Element, max_decrease_k_e_in_percent: float, max_increase_k_e_in_percent: float, maximum_k_e_is_calculated_wrt_maximum_k_e_of_section: bool = False, reference_elements: list[Element] | None = None, **kwargs, ) -> tuple[float, float]: r"""Get classic limits for ``k_e``. Parameters ---------- reference_element : Element The nominal element. max_decrease_in_percent : float Allowed decrease in percent with respect to the nominal ``k_e``. max_increase_in_percent : float Allowed increase in percent with respect to the nominal ``k_e``. maximum_k_e_is_calculated_wrt_maximum_k_e_of_section : bool, optional Use this flag to compute allowed increase of ``k_e`` with respect to the maximum ``k_e`` of the section, instead of the ``k_e`` of the nominal cavity. This is what we used in :cite:`Placais2022a`. The default is False. reference_elements : list[Element] | None List of the nominal elements. Must be provided if ``maximum_k_e_is_calculated_wrt_maximum_k_e_of_section`` is True. Returns ------- tuple[float, float] Lower and upper bounds for ``k_e``. """ reference_k_e = same_value_as_nominal("k_e", reference_element) min_k_e = reference_k_e * (1.0 - 1e-2 * max_decrease_k_e_in_percent) max_k_e = reference_k_e * (1.0 + 1e-2 * max_increase_k_e_in_percent) if not maximum_k_e_is_calculated_wrt_maximum_k_e_of_section: return (min_k_e, max_k_e) section_idx = reference_element.idx["section"] assert reference_elements is not None max_k_e_of_section = _get_maximum_k_e_of_section( section_idx, reference_elements ) max_k_e = max_k_e_of_section * (1.0 + 1e-2 * max_increase_k_e_in_percent) return (min_k_e, max_k_e)
[docs] def _get_maximum_k_e_of_section( section_idx: int, reference_elements: list[Element], ) -> float: """Get the maximum ``k_e`` of section.""" elements_in_current_section = list( filter( lambda element: element.idx["section"] == section_idx, reference_elements, ) ) k_e_in_current_section = [ element.get("k_e", to_numpy=False) for element in elements_in_current_section ] maximum_k_e = np.nanmax(k_e_in_current_section) return maximum_k_e
LIMITS_CALCULATORS = { "phi_s": phi_s_limits, "phi_0_abs": phi_0_limits, "phi_0_rel": phi_0_limits, "k_e": k_e_limits, }