Source code for materforge.core.elements

import logging
import sympy as sp
from dataclasses import dataclass
from typing import List, Union

logger = logging.getLogger(__name__)


[docs] @dataclass class ChemicalElement: name: str atomic_number: float atomic_mass: float melting_temperature: float boiling_temperature: float latent_heat_of_fusion: float latent_heat_of_vaporization: float
# Utility functions for element property interpolation def interpolate(values: List[float], composition: List[float]) -> Union[float, sp.Expr]: """ Interpolates a property based on its values and composition. Args: values (list): List of property values. composition (list): List of composition percentages. Returns: float: Interpolated property value. """ if len(values) != len(composition): logger.error("Length mismatch: values=%d, composition=%d", len(values), len(composition)) raise ValueError(f"Values and composition arrays must have same length: {len(values)} vs {len(composition)}") logger.debug("Interpolating property with %d components", len(values)) result = 0. for i, (v, c) in enumerate(zip(values, composition)): if c < 0 or c > 1: logger.warning("Composition value %d out of range [0,1]: %f", i, c) result += v * c logger.debug("Component %d: value=%.3f, composition=%.3f, contribution=%.3f", i, v, c, v*c) logger.debug("Interpolation result: %.6f", result) return result def interpolate_atomic_number(elements: List[ChemicalElement], composition: List[float]) -> float: """ Interpolates the atomic number based on the elements and their composition. Args: elements (list[ChemicalElement]): List of elements. composition (list[float]): List of composition percentages. Returns: float: Interpolated atomic number. """ logger.debug("Interpolating atomic number for %d elements", len(elements)) values = [element.atomic_number for element in elements] result = interpolate(values, composition) logger.info("Interpolated atomic number: %.3f", result) return result def interpolate_atomic_mass(elements: List[ChemicalElement], composition: List[float]) -> float: """ Interpolates the atomic mass based on the elements and their composition. Args: elements (list[ChemicalElement]): List of elements. composition (list[float]): List of composition percentages. Returns: float: Interpolated atomic mass. """ logger.debug("Interpolating atomic mass for %d elements", len(elements)) values = [element.atomic_mass for element in elements] result = interpolate(values, composition) logger.info("Interpolated atomic mass: %.3f g/mol", result) return result def interpolate_melting_temperature(elements: List[ChemicalElement], composition: List[float]) -> float: """ Interpolates the melting temperature based on the elements and their composition. """ logger.debug("Interpolating melting temperature for %d elements", len(elements)) values = [element.melting_temperature for element in elements] result = interpolate(values, composition) logger.info("Interpolated melting temperature: %.1f K", result) return result def interpolate_boiling_temperature(elements: List[ChemicalElement], composition: List[float]) -> float: """ Interpolates the boiling temperature based on the elements and their composition. Args: elements (list[ChemicalElement]): List of elements. composition (list[float]): List of composition percentages. Returns: float: Interpolated boiling temperature. """ logger.debug("Interpolating boiling temperature for %d elements", len(elements)) values = [element.boiling_temperature for element in elements] result = interpolate(values, composition) logger.info("Interpolated boiling temperature: %.1f K", result) return result