Source code for fdtd.materials

"""This module implements the objects."""
from __future__ import annotations

import json
from typing import List

from .exceptions import MaterialExists, MaterialNotFound


class MaterialMeta(type):
    """Material metaclass."""

    @property
    def all(cls) -> List["Material"]:
        """Return list of all materials registered."""
        return list(cls.__dict__["__materials__"])

    def __prepare__(cls, name):
        """Implement prepare function."""
        return {"__materials__": set()}

    def __getitem__(cls, name: str):
        """Return a material given a name."""
        for material in cls.__dict__["__materials__"]:
            if name == material.name:
                return material
        raise MaterialNotFound(f"Material {name} not found.")


[docs]class Material(metaclass=MaterialMeta): """Implement a material. Parameters ---------- name : str The name of the material. eps_r : float Relative permissivity. mu_r : float Relative permeability. sigma_e : float Electric condutivity. sigma_m : float Magnetic condutivity. color : str RGB color. """ def __init__( self, name: str, eps_r: float = 1, mu_r: float = 1, sigma_e: float = 0, sigma_m: float = 0, color: str = "#000000", ): """Initialize a material object.""" self.name = name self.eps_r = eps_r self.mu_r = mu_r self.sigma_e = sigma_e + 1e-20 self.sigma_m = sigma_m + 1e-20 self.color = color self._register(self) def _register(self, material: Material) -> None: materials_set = self.__class__.__dict__["__materials__"] if material not in materials_set: materials_set.add(material) else: raise MaterialExists(f"Material {material.name} already exists.") def _unregister(self, material): materials_set = self.__class__.__dict__["__materials__"] materials_set.discard(material) def _delete(self) -> None: """Delete material.""" self._unregister(self) def __del__(self): """Implement destructor.""" self._delete()
[docs] @classmethod def load(cls, file_name: str): """Load materials from a .json file. Parameters ---------- file_name : str Filename in the root directory. """ with open(file_name, "r") as f: data = json.load(f) for props in data: cls(**props)
[docs] @classmethod def from_name(cls, name: str) -> Material: """Initialize material from a name. Parameters ---------- name : str Name of material. Returns ------- Material Raises ------- MaterialNotFound If material is not found. Notes ------- Material[name] is equivalent to Material.from_name(name). """ for material in cls.__dict__["__materials__"]: if name == material.name: return material raise MaterialNotFound(f"Material {name} not found.")
def __hash__(self) -> int: """Implement hash function.""" return hash(self.name) def __eq__(self, other) -> bool: """Implement equal function.""" return self.name == other.name def __repr__(self) -> str: """Representation of the material.""" return f"Material({self.name})"