Source code for optimization.variable.material

"""Material Variable Module

This module contains the MaterialVariable class, which represents a variable for
the material at a specific surface such as a glass.
The variable can be used in optimization problems to optimize the material
at a specific surface.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from optiland.materials.abbe import AbbeMaterial
from optiland.materials.material_utils import find_closest_glass, get_nd_vd
from optiland.optimization.scaling.identity import IdentityScaler
from optiland.optimization.variable.base import VariableBehavior
from optiland.surfaces.factories.material_factory import MaterialFactory

if TYPE_CHECKING:
    from optiland.materials.base import BaseMaterial
    from optiland.optimization.scaling.base import Scaler


[docs] class MaterialVariable(VariableBehavior): """Represents a variable for the material at a specific surface. Args: optic (Optic): The optic object associated with the variable. surface_number (int): The surface number where the variable is applied. calculated. **kwargs: Additional keyword arguments. """ def __init__( self, optic, surface_number: int, glass_selection: list[str], scaler: Scaler = None, **kwargs, ): if scaler is None: scaler = IdentityScaler() super().__init__(optic, surface_number, scaler=scaler, **kwargs) self.glass_selection = glass_selection self.surface = self.optic.surfaces[self.surface_number] if isinstance(self.surface.material_post, AbbeMaterial): nd_vd = ( float(self.surface.material_post.index[0].item()), float(self.surface.material_post.abbe[0].item()), ) glass = find_closest_glass(nd_vd=nd_vd, catalog=glass_selection) new_nd, new_vd = get_nd_vd(glass) self.update_value(new_value=glass) print( f"The material of surface {surface_number:<2} is defined " f"by its AbbeMaterial {nd_vd}. GlassExpert converted it " f"to real material {glass:<7} ({new_nd:.4f}, {new_vd:.2f}) " f"to proceed with optimization." )
[docs] def get_value(self) -> str: """Returns the name of the material at the specified surface. Returns: str: The material name. """ return self.surface.material_post.name
[docs] def update_value(self, new_value: str) -> None: """Updates the material at the specified surface. Args: new_value (float): The new material name. """ material_post: BaseMaterial = MaterialFactory._configure_post_material( new_value ) self.optic.updater.set_material(material_post, self.surface_number)
def __str__(self) -> str: """Return a string representation of the variable. Returns: str: A string representation of the variable. """ return f"Material, Surface {self.surface_number}"