diff --git a/apps/HeatEquationKernelWithMaterial.py b/apps/HeatEquationKernelWithMaterial.py
index 5a5929867231232d8c12d48ab1f12a8d7b90a5ce..8c489d185d099f635b6ed9e0e64087250d242819 100644
--- a/apps/HeatEquationKernelWithMaterial.py
+++ b/apps/HeatEquationKernelWithMaterial.py
@@ -23,7 +23,6 @@ with SourceFileGenerator() as sfg:
 
     yaml_path = files('pymatlib.data.alloys.SS316L').joinpath('SS304L.yaml')
     mat = create_alloy_from_yaml(yaml_path, u.center())
-    # arr_container = DoubleLookupArrayContainer("SS316L", mat.temperature_array, mat.energy_density_array)
     arr_container = InterpolationArrayContainer.from_material("SS316L", mat)
     sfg.generate(arr_container)
 
@@ -39,6 +38,5 @@ with SourceFileGenerator() as sfg:
             ps.Assignment(thermal_diffusivity_out.center(), thermal_diffusivity)
         ])
 
-    # generate_sweep(ctx, 'HeatEquationKernelWithMaterial', ac, varying_parameters=((data_type, str(thermal_diffusivity)),))
     sweep = Sweep("HeatEquationKernelWithMaterial", ac)
     sfg.generate(sweep)
diff --git a/apps/walberla b/apps/walberla
index 0aab9c0af2335b1f6fec75deae06e514ccb233ab..3a09f7b17ce244123214ed2675a54896786233d9 160000
--- a/apps/walberla
+++ b/apps/walberla
@@ -1 +1 @@
-Subproject commit 0aab9c0af2335b1f6fec75deae06e514ccb233ab
+Subproject commit 3a09f7b17ce244123214ed2675a54896786233d9
diff --git a/src/pymatlib/core/data_handler.py b/src/pymatlib/core/data_handler.py
index 0ce948709c0725c82c99614884d411c8c51886fa..8b71b33d159d1d900e42081b63aec8439f76b6ec 100644
--- a/src/pymatlib/core/data_handler.py
+++ b/src/pymatlib/core/data_handler.py
@@ -449,7 +449,7 @@ if __name__ == '__main__':
     # Example usage:
     # 1. Using a file path
     base_dir = Path(__file__).parent  # Directory of the current file
-    _file_path = str( base_dir / '..' / 'data' / 'alloys' / 'SS316L' / 'density_temperature.txt' )
+    _file_path = str( base_dir / '..' / 'data' / 'alloys' / 'SS304L' / 'density_temperature.txt' )
     min_temp, max_temp = find_min_max_temperature(_file_path)
     print(f"Minimum Temperature from file: {min_temp}")
     print(f"Maximum Temperature from file: {max_temp}")
diff --git a/src/pymatlib/core/interpolators.py b/src/pymatlib/core/interpolators.py
index d00d314707b70b7537f47890bf59fb050b72d231..fc3a06de930daa65015bef3c79120cab994762fc 100644
--- a/src/pymatlib/core/interpolators.py
+++ b/src/pymatlib/core/interpolators.py
@@ -405,10 +405,13 @@ def prepare_interpolation_arrays(T_array: np.ndarray, E_array: np.ndarray) -> di
 
     # Basic validation
     if len(T_array) != len(E_array):
-        raise ValueError("Temperature and energy density arrays must have the same length")
+        raise ValueError(f"Energy density array (length {len(E_array)}) and temperature array (length {len(T_array)}) must have the same length!")
 
-    if len(T_array) < 2:
-        raise ValueError("Arrays must contain at least 2 elements")
+    if not E_array.size or not T_array.size:
+        raise ValueError("Energy density and temperature arrays must not be empty!")
+
+    if len(E_array) < 2:
+        raise ValueError(f"Arrays must contain at least 2 elements, got {len(E_array)}!")
 
     # Check if arrays are monotonic
     T_increasing = np.all(np.diff(T_array) > 0)
diff --git a/src/pymatlib/core/yaml_parser.py b/src/pymatlib/core/yaml_parser.py
index d2889a36b2e054f1e5dd1ef001c9f8844db0a0eb..eab110edfe66e6074ad6a600933d4267b30b3187 100644
--- a/src/pymatlib/core/yaml_parser.py
+++ b/src/pymatlib/core/yaml_parser.py
@@ -12,9 +12,28 @@ from pymatlib.core.models import (density_by_thermal_expansion,
 from pymatlib.core.typedefs import MaterialProperty
 from ruamel.yaml import YAML, constructor, scanner
 from difflib import get_close_matches
+from enum import Enum, auto
+
+
+class PropertyType(Enum):
+    CONSTANT = auto()
+    FILE = auto()
+    KEY_VAL = auto()
+    COMPUTE = auto()
+    TUPLE_STRING = auto()
+    INVALID = auto()
 
 
 class MaterialConfigParser:
+
+    ##################################################
+    # Class Constants and Attributes
+    ##################################################
+
+    MIN_POINTS = 2
+    EPSILON = 1e-10  # Small value to handle floating point comparisons
+    ABSOLUTE_ZERO = 0.0  # Kelvin
+
     # Define valid properties as class-level constants
     VALID_PROPERTIES = {
         'base_temperature',
@@ -33,17 +52,20 @@ class MaterialConfigParser:
         'latent_heat_of_vaporization',
         'specific_enthalpy',
         'surface_tension',
+        'temperature',
         'temperature_array',
         'thermal_diffusivity',
         'thermal_expansion_coefficient',
     }
 
+    ##################################################
+    # Initialization and YAML Loading
+    ##################################################
+
     def __init__(self, yaml_path: str | Path) -> None:
         """Initialize parser with YAML file path.
-
         Args:
             yaml_path: Path to the YAML configuration file
-
         Raises:
             FileNotFoundError: If YAML file is not found
             ValueError: If configuration is invalid
@@ -57,13 +79,15 @@ class MaterialConfigParser:
 
     def _load_yaml(self) -> Dict[str, Any]:
         """Load and parse YAML file.
-
         Returns:
             Dict containing parsed YAML content
+        Raises:
+            FileNotFoundError: If YAML file is not found
+            constructor.DuplicateKeyError: If duplicate keys are found
+            scanner.ScannerError: If YAML syntax is invalid
         """
         yaml = YAML(typ='safe')
         yaml.allow_duplicate_keys = False
-
         try:
             with open(self.yaml_path, 'r') as f:
                 return yaml.load(f)
@@ -76,33 +100,45 @@ class MaterialConfigParser:
         except Exception as e:
             raise ValueError(f"Error parsing {self.yaml_path}: {str(e)}")
 
+    ##################################################
+    # Configuration Validation
+    ##################################################
+
     def _validate_config(self) -> None:
-        """Validate YAML configuration structure and content."""
+        """
+        Validate YAML configuration structure and content.
+        This method checks the overall structure of the configuration,
+        validates property names, required fields, and property values.
+        Raises:
+            ValueError: If any part of the configuration is invalid.
+        """
         if not isinstance(self.config, dict):
             # raise ValueError("Root YAML element must be a mapping")
             raise ValueError("The YAML file must start with a dictionary/object structure with key-value pairs, not a list or scalar value")
-
         if 'properties' not in self.config:
             raise ValueError("Missing 'properties' section in configuration")
-
         properties = self.config.get('properties', {})
         if not isinstance(properties, dict):
             # raise ValueError("'properties' must be a mapping")
             raise ValueError("The 'properties' section in your YAML file must be a dictionary with key-value pairs")
-
         self._validate_property_names(properties)
         self._validate_required_fields()
         self._validate_property_values(properties)
 
     def _validate_property_names(self, properties: Dict[str, Any]) -> None:
-        """Validate property names against allowed set."""
+        """
+        Validate property names against the allowed set.
+        Args:
+            properties (Dict[str, Any]): Dictionary of properties to validate.
+        Raises:
+            ValueError: If any property name is not in VALID_PROPERTIES.
+        """
         invalid_props = set(properties.keys()) - self.VALID_PROPERTIES
         if invalid_props:
             suggestions = {
                 prop: get_close_matches(prop, self.VALID_PROPERTIES, n=1, cutoff=0.6)
                 for prop in invalid_props
             }
-
             error_msg = "Invalid properties found:\n"
             for prop, matches in suggestions.items():
                 suggestion = f" (did you mean '{matches[0]}'?)" if matches else ""
@@ -110,214 +146,543 @@ class MaterialConfigParser:
             raise ValueError(error_msg)
 
     def _validate_required_fields(self) -> None:
-        """Validate required configuration fields."""
+        """
+        Validate required configuration fields.
+        Raises:
+            ValueError: If any required field is missing.
+        """
         required_fields = {'name', 'composition', 'solidus_temperature', 'liquidus_temperature'}
         missing_fields = required_fields - set(self.config.keys())
         if missing_fields:
             raise ValueError(f"Missing required fields: {', '.join(missing_fields)}")
 
-    def _validate_property_values(self, properties: Dict[str, Any]) -> None:
-        """Validate property values for type and range constraints."""
-        if 'density' in properties:
-            density = properties['density']
-            if isinstance(density, (int, float)) and density <= 0:
-                raise ValueError("Density must be positive")
-
-        if 'energy_density_temperature_array' in properties:
-            edta = properties['energy_density_temperature_array']
-            if isinstance(edta, tuple) and len(edta) != 3:
-                raise ValueError("Temperature array must be a tuple of (start, end, points/step)")
-
-########################################################################################################################
+    @staticmethod
+    def _validate_property_values(properties: Dict[str, Any]) -> None:
+        """
+        Validate property values for type and range constraints.
+        Args:
+            properties (Dict[str, Any]): Dictionary of properties to validate.
+        Raises:
+            ValueError: If any property value is invalid.
+        """
+        for prop_name, prop_value in properties.items():
+            BASE_PROPERTIES = {'base_temperature', 'base_density'}
+            POSITIVE_PROPERTIES = {'density', 'heat_capacity', 'heat_conductivity', 'specific_enthalpy'}
+            NON_NEGATIVE_PROPERTIES = {'latent_heat'}
+            if prop_value is None or (isinstance(prop_value, str) and prop_value.strip() == ''):
+                raise ValueError(f"Property '{prop_name}' has an empty or undefined value")
+            if prop_name in BASE_PROPERTIES:
+                if not isinstance(prop_value, float) or prop_value <= 0:
+                    raise ValueError(f"'{prop_name}' must be a positive number of type float, "
+                                     f"got {prop_value} of type {type(prop_value).__name__}")
+            if prop_name in POSITIVE_PROPERTIES:
+                if isinstance(prop_value, float) and prop_value <= 0:
+                    raise ValueError(f"'{prop_name}' must be positive, got {prop_value}")
+            if prop_name in NON_NEGATIVE_PROPERTIES:
+                if isinstance(prop_value, float) and prop_value < 0:
+                    raise ValueError(f"'{prop_name}' cannot be negative, got {prop_value}")
+            if prop_name == 'thermal_expansion_coefficient':
+                if isinstance(prop_value, float) and prop_value < -3e-5 or prop_value > 0.001:
+                    raise ValueError(f"'{prop_name}' value {prop_value} is outside the expected range (-3e-5/K to 0.001/K)")
+            if prop_name == 'energy_density_temperature_array':
+                if not (isinstance(prop_value, str) and prop_value.startswith('(') and prop_value.endswith(')')):
+                    raise ValueError(f"'{prop_name}' must be a tuple of three comma-separated values representing (start, end, points/step)")
+            if prop_name in ['energy_density_solidus', 'energy_density_liquidus']:
+                raise ValueError(f"{prop_name} cannot be set directly. It is computed from other properties")
+
+    ##################################################
+    # Alloy Creation
+    ##################################################
 
     def create_alloy(self, T: Union[float, sp.Symbol]) -> Alloy:
-        """Creates Alloy instance from YAML configuration"""
-        alloy = Alloy(
-            elements=self._get_elements(),
-            composition=list(self.config['composition'].values()),
-            temperature_solidus=self.config['solidus_temperature'],
-            temperature_liquidus=self.config['liquidus_temperature']
-        )
-        self._process_properties(alloy, T)
-        return alloy
+        """
+        Creates an Alloy instance from YAML configuration.
+        Args:
+            T (Union[float, sp.Symbol]): Temperature value or symbol.
+        Returns:
+            Alloy: An instance of the Alloy class.
+        Raises:
+            ValueError: If there's an error in creating the alloy.
+        """
+        try:
+            alloy = Alloy(
+                elements=self._get_elements(),
+                composition=list(self.config['composition'].values()),
+                temperature_solidus=self.config['solidus_temperature'],
+                temperature_liquidus=self.config['liquidus_temperature']
+            )
+            self._process_properties(alloy, T)
+            return alloy
+        except KeyError as e:
+            raise ValueError(f"Configuration error: Missing {e}")
+        except Exception as e:
+            raise ValueError(f"Failed to create alloy: {e}")
 
     def _get_elements(self) -> List[ChemicalElement]:
-        """Convert element symbols to ChemicalElement instances"""
+        """
+        Convert element symbols to ChemicalElement instances.
+        Returns:
+            List[ChemicalElement]: List of ChemicalElement instances.
+        Raises:
+            ValueError: If an invalid element symbol is encountered.
+        """
         from pymatlib.data.element_data import element_map
-        return [element_map[sym] for sym in self.config['composition'].keys()]
-
-    def _is_numeric(self, value: str) -> bool:
-        """Check if string represents a number (including scientific notation)"""
+        try:
+            return [element_map[sym] for sym in self.config['composition'].keys()]
+        except KeyError as e:
+            raise ValueError(f"Invalid element symbol: {e}")
+
+    ##################################################
+    # Property Type Checking
+    ##################################################
+    @staticmethod
+    def _is_numeric(value: str) -> bool:
+        """
+        Check if string represents a number (including scientific notation).
+        Args:
+            value (str): The string to check.
+        Returns:
+            bool: True if the string represents a number, False otherwise.
+        """
         try:
             float(value)
             return True
         except ValueError:
             return False
 
-    def _is_data_file(self, value: Dict[str, str]) -> bool:
-        """Check if dictionary represents a valid data file configuration"""
+    @staticmethod
+    def _is_data_file(value: str | Dict[str, str]) -> bool:
+        """
+        Check if the value represents a valid data file configuration.
+        Args:
+            value (Union[str, Dict[str, str]]): The value to check.
+        Returns:
+            bool: True if it's a valid data file configuration, False otherwise.
+        Raises:
+            ValueError: If the file configuration is invalid or contains extra keys.
+        """
         # Simple format: property_name: "filename.txt"
-        if isinstance(value, str) and (value.endswith('.txt') or value.endswith('.csv') or value.endswith('.xlsx')):
-            return True
+        if isinstance(value, str):
+            return value.endswith(('.txt', '.csv', '.xlsx'))
         # Advanced format: property_name: { file: "filename", temp_col: "col1", prop_col: "col2" }
-        if isinstance(value, dict) and 'file' in value:
-            # Required keys for advanced format
-            required_keys = ['file', 'temp_col', 'prop_col']
-            missing_keys = [k for k in required_keys if k not in value]
-
-            if missing_keys:
+        if isinstance(value, dict) and 'file' in value and 'temp_col' in value and 'prop_col' in value:
+            required_keys = {'file', 'temp_col', 'prop_col'}
+            value_keys = set(value.keys())
+            if not required_keys.issubset(value_keys):
+                missing_keys = required_keys - value_keys
                 raise ValueError(f"Missing required keys for file configuration: {missing_keys}")
+            if value_keys != required_keys:
+                extra_keys = value_keys - required_keys
+                raise ValueError(f"Extra keys found in file configuration: {extra_keys}")
             return True
         return False
 
-    def _is_key_val_property(self, value: Dict) -> bool:
-        """Check if property is defined with key-val pairs"""
-        return isinstance(value, dict) and 'key' in value and 'val' in value
+    @staticmethod
+    def _is_key_val_property(value: Any) -> bool:
+        """
+        Check if property is defined with key-val pairs.
+        Args:
+            value (Any): The value to check.
+        Returns:
+            bool: True if it's a key-val property, False otherwise.
+        Raises:
+            ValueError: If the key-val property configuration is invalid.
+        """
+        if isinstance(value, dict) and 'key' in value and 'val' in value:
+            required_keys = {'key', 'val'}
+            value_keys = set(value.keys())
+
+            if value_keys != required_keys:
+                missing_keys = required_keys - value_keys
+                extra_keys = value_keys - required_keys
+                if missing_keys:
+                    raise ValueError(f"Missing required keys for key-val property: {missing_keys}")
+                if extra_keys:
+                    raise ValueError(f"Extra keys found in key-val property: {extra_keys}")
+            return True
+        return False
 
-    def _is_compute_property(self, value: Any) -> bool:
-        """Check if property should be computed using any valid format"""
-        # Simple format: property_name: compute
+    @staticmethod
+    def _is_compute_property(value: Any) -> bool:
+        """
+        Check if property should be computed using any valid format.
+        Args:
+            value (Any): The value to check.
+        Returns:
+            bool: True if it's a compute property, False otherwise.
+        Raises:
+            ValueError: If the compute property configuration is invalid.
+        """
         if isinstance(value, str) and value == 'compute':
             return True
-        # Advanced format: property_name: { compute: "method_name" }
         elif isinstance(value, dict) and 'compute' in value:
-            # Ensure no other keys are present
-            invalid_keys = [k for k in value.keys() if k != 'compute']
-            if invalid_keys:
-                raise ValueError(f"Invalid keys in compute property: {invalid_keys}. Only 'compute' is allowed.")
+            required_keys = {'compute'}
+            value_keys = set(value.keys())
+
+            if value_keys != required_keys:
+                missing_keys = required_keys - value_keys
+                extra_keys = value_keys - required_keys
+                if missing_keys:
+                    raise ValueError(f"Missing required key for compute property: {missing_keys}")
+                if extra_keys:
+                    raise ValueError(f"Extra keys found in compute property: {extra_keys}")
             return True
         return False
 
-    def _process_properties(self, alloy: Alloy, T: Union[float, sp.Symbol]):
-        """Process all material properties in correct order"""
-        properties = self.config['properties']
-
-        # Step 1: Process constant float properties
-        for name, config in properties.items():
-            if isinstance(config, (int, float)) or (isinstance(config, str) and self._is_numeric(config)):
-                self._process_constant_property(alloy, name, config)
-
-        # Step 2: Process file-based properties
-        for name, config in properties.items():
-            if self._is_data_file(config):
-                self._process_file_property(alloy, name, config, T)
-
-        # Step 3: Process key-val pair properties
-        for name, config in properties.items():
-            if self._is_key_val_property(config):
-                self._process_key_val_property(alloy, name, config, T)
+    def _determine_property_type(self, prop_name: str, config: Any) -> PropertyType:
+        """
+        Determine the type of property based on its configuration.
+        Args:
+            prop_name (str): The name of the property.
+            config (Any): The configuration of the property.
+        Returns:
+            PropertyType: The determined property type.
+        """
+        if isinstance(config, float) or (isinstance(config, str) and self._is_numeric(config)):
+            return PropertyType.CONSTANT
+        elif self._is_data_file(config):
+            return PropertyType.FILE
+        elif self._is_key_val_property(config):
+            return PropertyType.KEY_VAL
+        elif self._is_compute_property(config):
+            return PropertyType.COMPUTE
+        elif prop_name == 'energy_density_temperature_array' and isinstance(config, str) and config.startswith('(') and config.endswith(')'):
+            return PropertyType.TUPLE_STRING
+        else:
+            return PropertyType.INVALID
 
-        # Step 4: Process computed properties
-        for name, config in properties.items():
-            if self._is_compute_property(config):
-                self._process_computed_property(alloy, name, T)
+    def _categorize_properties(self, properties: Dict[str, Any]) -> Dict[PropertyType, List[Tuple[str, Any]]]:
+        """
+        Categorize properties based on their types.
+        Args:
+            properties (Dict[str, Any]): Dictionary of properties to categorize.
+        Returns:
+            Dict[PropertyType, List[Tuple[str, Any]]]: Categorized properties.
+        Raises:
+            ValueError: If an invalid property configuration is found.
+        """
+        categorized_properties: Dict[PropertyType, List[Tuple[str, Any]]] = {
+            PropertyType.CONSTANT: [],
+            PropertyType.FILE: [],
+            PropertyType.KEY_VAL: [],
+            PropertyType.COMPUTE: [],
+            PropertyType.TUPLE_STRING: []
+        }
+        for prop_name, config in properties.items():
+            prop_type = self._determine_property_type(prop_name, config)
+            if prop_type == PropertyType.INVALID:
+                raise ValueError(f"Invalid configuration for property '{prop_name}': {config}")
+            categorized_properties[prop_type].append((prop_name, config))
+        return categorized_properties
+
+    ##################################################
+    # Property Processing
+    ##################################################
+
+    def _process_properties(self, alloy: Alloy, T: Union[float, sp.Symbol]) -> None:
+        """
+        Process all properties for the alloy.
+        Args:
+            alloy (Alloy): The alloy object to process properties for.
+            T (Union[float, sp.Symbol]): Temperature value or symbol.
+        Raises:
+            ValueError: If there's an error processing any property.
+        """
+        properties = self.config['properties']
+        try:
+            categorized_properties = self._categorize_properties(properties)
+            for prop_type, prop_list in categorized_properties.items():
+                for prop_name, config in prop_list:
+                    if prop_type == PropertyType.CONSTANT:
+                        self._process_constant_property(alloy, prop_name, config)
+                    elif prop_type == PropertyType.FILE:
+                        self._process_file_property(alloy, prop_name, config, T)
+                    elif prop_type == PropertyType.KEY_VAL:
+                        self._process_key_val_property(alloy, prop_name, config, T)
+                    elif prop_type == PropertyType.COMPUTE:
+                        self._process_computed_property(alloy, prop_name, T)
+                    elif prop_type == PropertyType.TUPLE_STRING:
+                        # Handle tuple string properties if needed
+                        pass
+        except Exception as e:
+            raise ValueError(f"Failed to process properties: {e}")
 
 ########################################################################################################################
 
-    def _process_constant_property(self, alloy: Alloy, prop_name: str, prop_config: Union[int, float, str]):
-        """Process constant float property"""
+    @staticmethod
+    def _process_constant_property(alloy: Alloy, prop_name: str, prop_config: Union[int, float, str]) -> None:
+        """
+        Process constant float property.
+        Args:
+            alloy (Alloy): The alloy object to update.
+            prop_name (str): The name of the property to set.
+            prop_config (Union[int, float, str]): The property value or string representation.
+        Raises:
+            ValueError: If the property value cannot be converted to float.
+        """
         try:
             value = float(prop_config)
             setattr(alloy, prop_name, value)
-        except (ValueError, TypeError):
-            raise ValueError(f"Invalid number format for {prop_name}: {prop_config}")
+        except (ValueError, TypeError) as e:
+            error_msg = f"Invalid number format for {prop_name}: {prop_config}"
+            raise ValueError(error_msg) from e
 
 ########################################################################################################################
 
-    def _process_file_property(self, alloy: Alloy, prop_name: str, file_config: Union[str, Dict], T: Union[float, sp.Symbol]):
-        """Process property data from file configuration"""
-        # Get the directory containing the YAML file
-        yaml_dir = self.base_dir
-
-        # Construct path relative to YAML file location
-        if isinstance(file_config, dict) and 'file' in file_config:
-            file_config['file'] = str(yaml_dir / file_config['file'])
-            temp_array, prop_array = read_data_from_file(file_config)
-        else:
-            # For string configuration, construct the full path
-            file_path = str(yaml_dir / file_config)
-            temp_array, prop_array = read_data_from_file(file_path)
-
-        # Store temperature array if not already set
-        if not hasattr(alloy, 'temperature_array') or len(alloy.temperature_array) == 0:
-            alloy.temperature_array = temp_array
-
-        material_property = interpolate_property(T, temp_array, prop_array)
-        setattr(alloy, prop_name, material_property)
-
-        # Store additional properties if this is energy_density
-        if prop_name == 'energy_density':
-            alloy.energy_density_temperature_array = temp_array
-            alloy.energy_density_array = prop_array
-            alloy.energy_density_solidus = material_property.evalf(T, alloy.temperature_solidus)
-            alloy.energy_density_liquidus = material_property.evalf(T, alloy.temperature_liquidus)
+    def _process_file_property(self, alloy: Alloy, prop_name: str, file_config: Union[str, Dict[str, Any]], T: Union[float, sp.Symbol]) -> None:
+        """
+        Process property data from file configuration.
+        Args:
+            alloy (Alloy): The alloy object to update.
+            prop_name (str): The name of the property to set.
+            file_config (Union[str, Dict[str, Any]]): File path or configuration dictionary.
+            T (Union[float, sp.Symbol]): Temperature value or symbol.
+        Raises:
+            ValueError: If there's an error processing the file data.
+        """
+        try:
+            # Get the directory containing the YAML file
+            yaml_dir = self.base_dir
+            # Construct path relative to YAML file location
+            if isinstance(file_config, dict) and 'file' in file_config:
+                file_config['file'] = str(yaml_dir / file_config['file'])
+                temp_array, prop_array = read_data_from_file(file_config)
+            else:
+                # For string configuration, construct the full path
+                file_path = str(yaml_dir / file_config)
+                temp_array, prop_array = read_data_from_file(file_path)
+            self._process_property_data(alloy, prop_name, T, temp_array, prop_array)
+        except Exception as e:
+            error_msg = f"Error processing file property {prop_name}: {str(e)}"
+            raise ValueError(error_msg) from e
 
 ########################################################################################################################
 
-    def _process_key_val_property(self, alloy: Alloy, prop_name: str, prop_config: Dict, T: Union[float, sp.Symbol]):
-        """Process property defined with key-val pairs"""
-        key_array = self._process_key_definition(prop_config['key'], prop_config['val'], alloy)
-        val_array = np.array(prop_config['val'], dtype=float)
-
-        if len(key_array) != len(val_array):
-            raise ValueError(f"Length mismatch in {prop_name}: key and val arrays must have same length")
-
-        # Store temperature array if not already set
-        if not hasattr(alloy, 'temperature_array') or len(alloy.temperature_array) == 0:
-            alloy.temperature_array = key_array
-
-        material_property = interpolate_property(T, key_array, val_array)
-        setattr(alloy, prop_name, material_property)
-
-        # Store additional properties if this is energy_density
-        if prop_name == 'energy_density':
-            alloy.energy_density_temperature_array = key_array
-            alloy.energy_density_array = val_array
-            alloy.energy_density_solidus = material_property.evalf(T, alloy.temperature_solidus)
-            alloy.energy_density_liquidus = material_property.evalf(T, alloy.temperature_liquidus)
+    def _process_key_val_property(self, alloy: Alloy, prop_name: str, prop_config: Dict, T: Union[float, sp.Symbol]) -> None:
+        """
+        Process property defined with key-val pairs.
+        Args:
+            alloy (Alloy): The alloy object to update.
+            prop_name (str): The name of the property to set.
+            prop_config (Dict[str, Any]): The property configuration dictionary.
+            T (Union[float, sp.Symbol]): Temperature value or symbol.
+        Raises:
+            ValueError: If there's an error processing the key-val property.
+        """
+        try:
+            key_array = self._process_key_definition(prop_config['key'], prop_config['val'], alloy)
+            val_array = np.array(prop_config['val'], dtype=float)
+            if len(key_array) != len(val_array):
+                raise ValueError(f"Length mismatch in {prop_name}: key and val arrays must have same length")
+            self._process_property_data(alloy, prop_name, T, key_array, val_array)
+        except Exception as e:
+            error_msg = f"Error processing key-val property {prop_name}: {str(e)}"
+            raise ValueError(error_msg) from e
 
     def _process_key_definition(self, key_def, val_array, alloy: Alloy) -> np.ndarray:
-        """Process temperature key definition"""
-        if isinstance(key_def, str) and key_def.startswith('(') and key_def.endswith(')'):
-            return self._process_equidistant_key(key_def, len(val_array))
-        elif isinstance(key_def, list):
-            return self._process_list_key(key_def, alloy)
-        else:
-            raise ValueError(f"Invalid key definition: {key_def}")
+        """
+        Process temperature key definition.
+        Args:
+            key_def (Union[str, List[Union[str, float]]]): The key definition.
+            val_array (List[float]): The value array.
+            alloy (Alloy): The alloy object.
+        Returns:
+            np.ndarray: Processed key array.
+        Raises:
+            ValueError: If there's an error processing the key definition.
+        """
+        try:
+            if isinstance(key_def, str) and key_def.startswith('(') and key_def.endswith(')'):
+                return self._process_equidistant_key(key_def, len(val_array))
+            elif isinstance(key_def, list):
+                return self._process_list_key(key_def, alloy)
+            else:
+                raise ValueError(f"Invalid key definition: {key_def}")
+        except Exception as e:
+            error_msg = f"Error processing key definition: {str(e)}"
+            raise ValueError(error_msg) from e
 
-    def _process_equidistant_key(self, key_def: str, n_points: int) -> np.ndarray:
-        """Process equidistant key definition"""
+    @staticmethod
+    def _process_equidistant_key(key_def: str, n_points: int) -> np.ndarray:
+        """
+        Process equidistant key definition.
+        Args:
+            key_def (str): The equidistant key definition string.
+            n_points (int): Number of points.
+        Returns:
+            np.ndarray: Equidistant key array.
+        Raises:
+            ValueError: If there's an error processing the equidistant key.
+        """
         try:
             values = [float(x.strip()) for x in key_def.strip('()').split(',')]
             if len(values) != 2:
                 raise ValueError("Equidistant definition must have exactly two values: (start, increment)")
             start, increment = values
-            return np.arange(start, start + increment * n_points, increment)
-        except ValueError as e:
-            raise ValueError(f"Invalid equidistant format: {key_def}. Error: {str(e)}")
-
-    def _process_list_key(self, key_def: List, alloy: Alloy) -> np.ndarray:
-        """Process list key definition"""
-        processed_key = []
-        for k in key_def:
-            if isinstance(k, str):
-                if k == 'solidus_temperature':
-                    processed_key.append(alloy.temperature_solidus)
-                elif k == 'liquidus_temperature':
-                    processed_key.append(alloy.temperature_liquidus)
+            key_array = np.arange(start, start + increment * n_points, increment)
+            return key_array
+        except Exception as e:
+            error_msg = f"Invalid equidistant format: {key_def}. Error: {str(e)}"
+            raise ValueError(error_msg) from e
+
+    @staticmethod
+    def _process_list_key(key_def: List, alloy: Alloy) -> np.ndarray:
+        """
+        Process list key definition.
+        Args:
+            key_def (List[Union[str, float]]): The list key definition.
+            alloy (Alloy): The alloy object.
+        Returns:
+            np.ndarray: Processed list key array.
+        Raises:
+            ValueError: If there's an error processing the list key.
+        """
+        try:
+            processed_key = []
+            for k in key_def:
+                if isinstance(k, str):
+                    if k == 'solidus_temperature':
+                        processed_key.append(alloy.temperature_solidus)
+                    elif k == 'liquidus_temperature':
+                        processed_key.append(alloy.temperature_liquidus)
+                    else:
+                        processed_key.append(float(k))
                 else:
                     processed_key.append(float(k))
+            key_array = np.array(processed_key, dtype=float)
+            return key_array
+        except Exception as e:
+            error_msg = f"Error processing list key: {str(e)}"
+            raise ValueError(error_msg) from e
+
+    ##################################################
+    # Property Data Processing
+    ##################################################
+
+    def _process_property_data(self, alloy: Alloy, prop_name: str, T: Union[float, sp.Symbol], temp_array: np.ndarray, prop_array: np.ndarray) -> None:
+        """
+        Process property data and set it on the alloy object.
+        Args:
+            alloy (Alloy): The alloy object to update.
+            prop_name (str): The name of the property to set.
+            T (Union[float, sp.Symbol]): Temperature value or symbol.
+            temp_array (np.ndarray): Array of temperature values.
+            prop_array (np.ndarray): Array of property values.
+        Raises:
+            ValueError: If there's an error processing the property data.
+        """
+        try:
+            if isinstance(T, sp.Symbol):
+                self._process_symbolic_temperature(alloy, prop_name, T, temp_array, prop_array)
+            elif isinstance(T, (float, int)):
+                self._process_constant_temperature(alloy, prop_name, T, temp_array, prop_array)
             else:
-                processed_key.append(float(k))
-        return np.array(processed_key, dtype=float)
+                raise ValueError(f"Unexpected type for T: {type(T)}")
+        except Exception as e:
+            error_msg = f"Error processing property data for {prop_name}: {str(e)}"
+            raise ValueError(error_msg) from e
 
-########################################################################################################################
+    def _process_symbolic_temperature(self, alloy: Alloy, prop_name: str, T: sp.Symbol, temp_array: np.ndarray, prop_array: np.ndarray) -> None:
+        """
+        Process property data for symbolic temperature.
+        Args:
+            alloy (Alloy): The alloy object to update.
+            prop_name (str): The name of the property to set.
+            T (sp.Symbol): Symbolic temperature.
+            temp_array (np.ndarray): Array of temperature values.
+            prop_array (np.ndarray): Array of property values.
+        """
+        # If T is symbolic, store the full temperature array if not already set then interpolate
+        if getattr(alloy, 'temperature_array', None) is None or len(alloy.temperature_array) == 0:
+            alloy.temperature_array = temp_array
+        material_property = interpolate_property(T, temp_array, prop_array)
+        setattr(alloy, prop_name, material_property)
+        if prop_name == 'energy_density':
+            self._process_energy_density(alloy, material_property, T, temp_array, prop_array)
 
-    def _process_computed_property(self, alloy: Alloy, prop_name: str, T: Union[float, sp.Symbol]):
-        """Process computed properties using predefined models with dependency checking"""
+    @staticmethod
+    def _process_constant_temperature(alloy: Alloy, prop_name: str, T: Union[float, int], temp_array: np.ndarray, prop_array: np.ndarray) -> None:
+        """
+        Process property data for constant temperature.
+        Args:
+            alloy (Alloy): The alloy object to update.
+            prop_name (str): The name of the property to set.
+            T (Union[float, int]): Constant temperature value.
+            temp_array (np.ndarray): Array of temperature values.
+            prop_array (np.ndarray): Array of property values.
+        """
+        # If T is a constant, store just that value if not already set then interpolate
+        if getattr(alloy, 'temperature', None) is None:
+            alloy.temperature = float(T)
+        material_property = interpolate_property(T, temp_array, prop_array)
+        setattr(alloy, prop_name, material_property)
 
-        # Define property dependencies and their computation methods
-        computation_methods = {
+    @staticmethod
+    def _process_energy_density(alloy: Alloy, material_property: Any, T: sp.Symbol, temp_array: np.ndarray, prop_array: np.ndarray) -> None:
+        """
+        Process additional properties for energy density.
+        Args:
+            alloy (Alloy): The alloy object to update.
+            material_property (Any): The interpolated material property.
+            T (sp.Symbol): Symbolic temperature.
+            temp_array (np.ndarray): Array of temperature values.
+            prop_array (np.ndarray): Array of property values.
+        """
+        alloy.energy_density_temperature_array = temp_array
+        alloy.energy_density_array = prop_array
+        alloy.energy_density_solidus = material_property.evalf(T, alloy.temperature_solidus)
+        alloy.energy_density_liquidus = material_property.evalf(T, alloy.temperature_liquidus)
+
+    ##################################################
+    # Computed Property Handling
+    ##################################################
+
+    def _process_computed_property(self, alloy: Alloy, prop_name: str, T: Union[float, sp.Symbol]) -> None:
+        """
+        Process computed properties using predefined models with dependency checking.
+        Args:
+            alloy (Alloy): The alloy object to process.
+            prop_name (str): The name of the property to compute.
+            T (Union[float, Symbol]): The temperature value or symbol.
+        Raises:
+            ValueError: If no computation method is defined for the property or if the method is unknown.
+        """
+        computation_methods = self._get_computation_methods(alloy, T)
+        dependencies = self._get_dependencies()
+        # Check if property has computation methods
+        if prop_name not in computation_methods:
+            raise ValueError(f"No computation method defined for property: {prop_name}")
+        # Determine which computation method to use
+        prop_config = self.config['properties'][prop_name]
+        method = 'default'
+        if isinstance(prop_config, dict) and 'compute' in prop_config:
+            method = prop_config['compute']
+        # Validate method exists
+        if method not in computation_methods[prop_name]:
+            available_methods = list(computation_methods[prop_name].keys())
+            raise ValueError(f"Unknown computation method '{method}' for {prop_name}. Available: {available_methods}")
+        # Get dependencies for selected method
+        method_dependencies = dependencies[prop_name][method]
+        # Process dependencies
+        self._process_dependencies(alloy, prop_name, method_dependencies, T)
+        # Compute property
+        material_property = computation_methods[prop_name][method]()
+        setattr(alloy, prop_name, material_property)
+        # Handle special case for energy_density
+        if prop_name == 'energy_density' and isinstance(T, sp.Symbol):
+            self._handle_energy_density(alloy, material_property, T, method_dependencies)
+
+    @staticmethod
+    def _get_computation_methods(alloy: Alloy, T: Union[float, sp.Symbol]):
+        """
+        Get the computation methods for various properties of the alloy.
+        Args:
+            alloy (Alloy): The alloy object containing property data.
+            T (Union[float, sp.Symbol]): The temperature value or symbol.
+        Returns:
+            dict: A dictionary of computation methods for different properties.
+        """
+        return {
             'density': {
                 'default': lambda: density_by_thermal_expansion(
                     T,
@@ -348,12 +713,19 @@ class MaterialConfigParser:
                 'total_enthalpy': lambda: energy_density_total_enthalpy(
                     alloy.density,
                     alloy.specific_enthalpy
-                )
+                ),
             },
         }
 
-        # Define property dependencies for each computation method
-        dependencies = {
+    @staticmethod
+    def _get_dependencies():
+        """
+        Get the dependencies for each computation method.
+        Returns:
+            dict: A nested dictionary specifying the dependencies for each
+                  computation method of each property.
+        """
+        return {
             'density': {
                 'default': ['base_temperature', 'base_density', 'thermal_expansion_coefficient'],
             },
@@ -367,94 +739,123 @@ class MaterialConfigParser:
             },
         }
 
-        # Check if property has computation methods
-        if prop_name not in computation_methods:
-            raise ValueError(f"No computation method defined for property: {prop_name}")
-
-        # Determine which computation method to use
-        prop_config = self.config['properties'][prop_name]
-        method = 'default'
-
-        if isinstance(prop_config, dict) and 'compute' in prop_config:
-            method = prop_config['compute']
-
-        # Validate method exists
-        if method not in computation_methods[prop_name]:
-            available_methods = list(computation_methods[prop_name].keys())
-            raise ValueError(f"Unknown computation method '{method}' for {prop_name}. Available: {available_methods}")
-
-        # Get dependencies for selected method
-        method_dependencies = dependencies[prop_name][method]
-
-        # Process dependencies first if they're marked for computation
-        if prop_name == 'energy_density':
-            if 'energy_density_temperature_array' not in self.config['properties']:
-                raise ValueError(f"energy_density_temperature_array must be defined when energy_density is computed")
-
-            # Process energy_density_temperature_array
-            edta = self.config['properties']['energy_density_temperature_array']
-            alloy.energy_density_temperature_array = self._process_edta(edta)
-
-        # Process other dependencies
-        for dep in method_dependencies:
-            if hasattr(alloy, dep) and getattr(alloy, dep) is None:
+    def _process_dependencies(self, alloy: Alloy, prop_name: str, dependencies: List[str], T: Union[float, sp.Symbol]):
+        """
+        Process and compute the dependencies required for a given property.
+        This method checks if each dependency is already computed for the alloy.
+        If not, it attempts to compute the dependency if a computation method is defined.
+        Args:
+            alloy (Alloy): The alloy object to process.
+            prop_name (str): The name of the property being computed.
+            dependencies (List[str]): List of dependency names for the property.
+            T (Union[float, sp.Symbol]): The temperature value or symbol.
+        Raises:
+            ValueError: If any required dependency cannot be computed or is missing.
+        """
+        for dep in dependencies:
+            if getattr(alloy, dep, None) is None:
                 if dep in self.config['properties']:
                     dep_config = self.config['properties'][dep]
                     if dep_config == 'compute' or (isinstance(dep_config, dict) and 'compute' in dep_config):
                         self._process_computed_property(alloy, dep, T)
-
         # Verify all dependencies are available
-        missing_deps = [dep for dep in method_dependencies
-                        if not hasattr(alloy, dep) or getattr(alloy, dep) is None]
+        missing_deps = [dep for dep in dependencies if getattr(alloy, dep, None) is None]
         if missing_deps:
             raise ValueError(f"Cannot compute {prop_name}. Missing dependencies: {missing_deps}")
 
-        # Compute property
-        material_property = computation_methods[prop_name][method]()
-        setattr(alloy, prop_name, material_property)
+    def _handle_energy_density(self, alloy: Alloy, material_property: MaterialProperty, T: sp.Symbol, dependencies: List[str]):
+        """
+        Handle the special case of energy density computation.
+        This method computes additional properties related to energy density when T is symbolic.
+        It computes the energy density array, solidus, and liquidus values.
+        Args:
+            alloy (Alloy): The alloy object to process.
+            material_property (MaterialProperty): The computed energy density property.
+            T (sp.Symbol): The symbolic temperature variable.
+            dependencies (List[str]): List of dependencies for energy density computation.
+        Raises:
+            ValueError: If T is not symbolic or if energy_density_temperature_array is not defined in the config.
+        """
+        # Ensure T is symbolic
+        if not isinstance(T, sp.Symbol):
+            raise ValueError("_handle_energy_density should only be called with symbolic T")
+        # Check dependencies
+        deps_to_check = [getattr(alloy, dep) for dep in dependencies if hasattr(alloy, dep)]
+        if any(isinstance(dep, MaterialProperty) for dep in deps_to_check):
+            if 'energy_density_temperature_array' not in self.config['properties']:
+                raise ValueError(f"energy_density_temperature_array must be defined when energy_density is computed with symbolic T")
+            # Process energy_density_temperature_array
+            edta = self.config['properties']['energy_density_temperature_array']
+            alloy.energy_density_temperature_array = self._process_edta(edta)
+        if len(alloy.energy_density_temperature_array) >= 2:
+            alloy.energy_density_array = material_property.evalf(T, alloy.energy_density_temperature_array)
+            alloy.energy_density_solidus = material_property.evalf(T, alloy.temperature_solidus)
+            alloy.energy_density_liquidus = material_property.evalf(T, alloy.temperature_liquidus)
 
-        # Handle special case for energy_density arrays and phase points
-        if prop_name == 'energy_density':
-            # Check if any dependency is a MaterialProperty
-            deps_to_check = [getattr(alloy, dep) for dep in method_dependencies if hasattr(alloy, dep)]
-            if any(isinstance(dep, MaterialProperty) for dep in deps_to_check):
-                if hasattr(alloy, 'energy_density_temperature_array') and len(alloy.energy_density_temperature_array) > 0:
-                    alloy.energy_density_array = np.array([
-                        material_property.evalf(T, temp) for temp in alloy.energy_density_temperature_array
-                    ])
-                    alloy.energy_density_solidus = material_property.evalf(T, alloy.temperature_solidus)
-                    alloy.energy_density_liquidus = material_property.evalf(T, alloy.temperature_liquidus)
+    ##################################################
+    # Energy Density Temperature Array Processing
+    ##################################################
 
     def _process_edta(self, array_def: str) -> np.ndarray:
-        """Process temperature array definition with format (start, end, points/delta)"""
+        """
+        Process temperature array definition with format (start, end, points/delta).
+        Args:
+            array_def (str): A string defining the temperature array in the format
+                             "(start, end, points/delta)".
+        Returns:
+            np.ndarray: An array of temperature values.
+        Raises:
+            ValueError: If the array definition is invalid, improperly formatted,
+                        or contains physically impossible temperatures.
+        Examples:
+            >>> self._process_edta("(300, 3000, 5)")
+            array([ 300., 975., 1650., 2325., 3000.])
+            >>> self._process_edta("(3000, 300, -1350.)")
+            array([3000., 1650., 300.])
+        """
         if not (isinstance(array_def, str) and array_def.startswith('(') and array_def.endswith(')')):
             raise ValueError("Temperature array must be defined as (start, end, points/delta)")
-
         try:
             # Parse the tuple string
             values = [v.strip() for v in array_def.strip('()').split(',')]
             if len(values) != 3:
-                raise ValueError("Temperature array definition must have exactly three values")
-
-            start = float(values[0])
-            end = float(values[1])
-            step = values[2]
-
+                raise ValueError("'energy_density_temperature_array' must be a tuple of three comma-separated values representing (start, end, points/step)")
+            start, end, step = float(values[0]), float(values[1]), values[2]
+            if start <= self.ABSOLUTE_ZERO or end <= self.ABSOLUTE_ZERO:
+                raise ValueError(f"Temperature must be above absolute zero ({self.ABSOLUTE_ZERO}K)")
+            if abs(float(step)) < self.EPSILON:
+                raise ValueError("Delta or number of points cannot be zero.")
             # Check if step represents delta (float) or points (int)
             if '.' in step or 'e' in step.lower():
-                delta = float(step)
-                return np.arange(start, end + delta/2, delta)  # delta/2 ensures end point inclusion
+                return self._process_float_step(start, end, float(step))
             else:
-            # Handle as points (int)
-                points = int(step)
-                if points <= 0:
-                    raise ValueError(f"Number of points must be a positive integer, got {points}")
-                return np.linspace(start, end, points)
-
+                return self._process_int_step(start, end, int(step))
         except ValueError as e:
             raise ValueError(f"Invalid temperature array definition: {e}")
 
-########################################################################################################################
+    @staticmethod
+    def _process_float_step(start: float, end: float, delta: float) -> np.ndarray:
+        """Process temperature array with float step (delta)."""
+        if start < end and delta <= 0:
+            raise ValueError("Delta must be positive for increasing range")
+        if start > end and delta >= 0:
+            raise ValueError("Delta must be negative for decreasing range")
+        max_delta = abs(end - start)
+        if abs(delta) > max_delta:
+            raise ValueError(f"Absolute value of delta ({abs(delta)}) is too large for the range. It should be <= {max_delta}")
+        return np.arange(start, end + delta/2, delta)
+
+    def _process_int_step(self, start: float, end: float, points: int) -> np.ndarray:
+        """Process temperature array with integer step (number of points)."""
+        if points <= 0:
+            raise ValueError(f"Number of points must be positive, got {points}!")
+        if points < self.MIN_POINTS:
+            raise ValueError(f"Number of points must be at least {self.MIN_POINTS}, got {points}!")
+        return np.linspace(start, end, points)
+
+##################################################
+# External Function
+##################################################
 
 def create_alloy_from_yaml(yaml_path: Union[str, Path], T: Union[float, sp.Symbol]) -> Alloy:
     """Create alloy instance from YAML configuration file"""
diff --git a/src/pymatlib/data/alloys/SS316L/304L_Erstarrungsdaten_edited.xlsx b/src/pymatlib/data/alloys/SS304L/304L_Erstarrungsdaten_edited.xlsx
similarity index 100%
rename from src/pymatlib/data/alloys/SS316L/304L_Erstarrungsdaten_edited.xlsx
rename to src/pymatlib/data/alloys/SS304L/304L_Erstarrungsdaten_edited.xlsx
diff --git a/src/pymatlib/data/alloys/SS316L/SS316L.py b/src/pymatlib/data/alloys/SS304L/SS304L.py
similarity index 81%
rename from src/pymatlib/data/alloys/SS316L/SS316L.py
rename to src/pymatlib/data/alloys/SS304L/SS304L.py
index 86de8aaa5025b51dbdb960d70aff1fe05cfd40a9..7483217f8a39de102dbf4b81ec1b4ff67e3bfd79 100644
--- a/src/pymatlib/data/alloys/SS316L/SS316L.py
+++ b/src/pymatlib/data/alloys/SS304L/SS304L.py
@@ -3,7 +3,6 @@ import numpy as np
 import sympy as sp
 from pathlib import Path
 from typing import Union
-from matplotlib import pyplot as plt
 from pymatlib.core.alloy import Alloy
 from pymatlib.data.element_data import Fe, Cr, Ni, Mo, Mn
 from pymatlib.core.models import thermal_diffusivity_by_heat_conductivity, density_by_thermal_expansion, energy_density, energy_density_total_enthalpy
@@ -11,13 +10,13 @@ from pymatlib.core.data_handler import read_data_from_txt, celsius_to_kelvin, th
 from pymatlib.core.interpolators import interpolate_property, prepare_interpolation_arrays, interpolate_binary_search, interpolate_double_lookup
 
 
-def create_SS316L(T: Union[float, sp.Symbol]) -> Alloy:
+def create_SS304L(T: Union[float, sp.Symbol]) -> Alloy:
     """
-    Creates an Alloy instance for SS316L stainless steel with specific properties.
+    Creates an Alloy instance for SS304L stainless steel with specific properties.
     Args:
         T (Union[float, sp.Symbol]): Temperature as a symbolic variable or numeric value.
     Returns:
-        Alloy: Initialized SS316L alloy with physical properties.
+        Alloy: Initialized SS304L alloy with physical properties.
     Notes:
         - **Material Properties**:
             - **Density**: 8.0 g/cm³ (8000 kg/m³) at room temperature
@@ -45,18 +44,18 @@ def create_SS316L(T: Union[float, sp.Symbol]) -> Alloy:
             - heat_conductivity_temperature.txt
     Example:
         >>> T = sp.Symbol('T')
-        >>> ss316l = create_SS316L(T)
+        >>> ss316l = create_SS304L(T)
         >>> density_at_1000K = ss316l.density.evalf(T, 1000.0)
     """
     # Define the alloy with specific elemental composition and phase transition temperatures
-    SS316L = Alloy(
+    SS304L = Alloy(
         elements=[Fe, Cr, Ni, Mo, Mn],
         composition=[0.675, 0.17, 0.12, 0.025, 0.01],  # Fe: 67.5%, Cr: 17%, Ni: 12%, Mo: 2.5%, Mn: 1%
         temperature_solidus=1605.,  # Solidus temperature in Kelvin (test at 1653.15 K = 1380 C)
         temperature_liquidus=1735.,  # Liquidus temperature in Kelvin (test at 1723.15 K = 1450 C)
         thermal_expansion_coefficient=16.3e-6  # in 1/K
     )
-    # density_data_file_path = "/local/ca00xebo/repos/pymatlib/src/pymatlib/data/alloys/SS316L/density_temperature.txt"
+    # density_data_file_path = "/local/ca00xebo/repos/pymatlib/src/pymatlib/data/alloys/SS304L/density_temperature.txt"
     # Determine the base directory
     base_dir = Path(__file__).parent  # Directory of the current file
 
@@ -65,8 +64,8 @@ def create_SS316L(T: Union[float, sp.Symbol]) -> Alloy:
     density_data_file_path = str(base_dir / '304L_Erstarrungsdaten_edited.xlsx')
     # heat_capacity_data_file_path = str(base_dir / 'heat_capacity_temperature_edited.txt')
     heat_capacity_data_file_path = str(base_dir / '304L_Erstarrungsdaten_edited.xlsx')
-    heat_conductivity_data_file_path = str(base_dir / '..' / 'SS316L' / '304L_Erstarrungsdaten_edited.xlsx')
-    latent_heat_of_fusion_data_file_path = str(base_dir / '..' / 'SS316L' / '304L_Erstarrungsdaten_edited.xlsx')
+    heat_conductivity_data_file_path = str(base_dir / '..' / 'SS304L' / '304L_Erstarrungsdaten_edited.xlsx')
+    latent_heat_of_fusion_data_file_path = str(base_dir / '..' / 'SS304L' / '304L_Erstarrungsdaten_edited.xlsx')
 
     # Read temperature and material property data from the files
     # density_temp_array, density_array = read_data_from_txt(density_data_file_path)
@@ -86,33 +85,33 @@ def create_SS316L(T: Union[float, sp.Symbol]) -> Alloy:
                                      heat_conductivity_temp_array, heat_conductivity_array]):
         raise ValueError("Failed to load temperature or material data from the file.")
 
-    SS316L.heat_conductivity = interpolate_property(T, heat_conductivity_temp_array, heat_conductivity_array)
-    SS316L.density = interpolate_property(T, density_temp_array, density_array)
-    SS316L.heat_capacity = interpolate_property(T, heat_capacity_temp_array, heat_capacity_array)
-    SS316L.thermal_diffusivity = thermal_diffusivity_by_heat_conductivity(SS316L.heat_conductivity, SS316L.density, SS316L.heat_capacity)
-    # SS316L.latent_heat_of_fusion = interpolate_property(T, SS316L.solidification_interval(), np.array([171401.0, 0.0]))
-    SS316L.latent_heat_of_fusion = interpolate_property(T, latent_heat_of_fusion_temp_array, latent_heat_of_fusion_array)
-    SS316L.specific_enthalpy = interpolate_property(T, density_temp_array, sp_enthalpy_array)
-    SS316L.energy_density = energy_density_total_enthalpy(SS316L.density, SS316L.specific_enthalpy)
-    SS316L.energy_density_solidus = SS316L.energy_density.evalf(T, SS316L.temperature_solidus)
-    SS316L.energy_density_liquidus = SS316L.energy_density.evalf(T, SS316L.temperature_liquidus)
+    SS304L.heat_conductivity = interpolate_property(T, heat_conductivity_temp_array, heat_conductivity_array)
+    SS304L.density = interpolate_property(T, density_temp_array, density_array)
+    SS304L.heat_capacity = interpolate_property(T, heat_capacity_temp_array, heat_capacity_array)
+    SS304L.thermal_diffusivity = thermal_diffusivity_by_heat_conductivity(SS304L.heat_conductivity, SS304L.density, SS304L.heat_capacity)
+    # SS304L.latent_heat_of_fusion = interpolate_property(T, SS304L.solidification_interval(), np.array([171401.0, 0.0]))
+    SS304L.latent_heat_of_fusion = interpolate_property(T, latent_heat_of_fusion_temp_array, latent_heat_of_fusion_array)
+    SS304L.specific_enthalpy = interpolate_property(T, density_temp_array, sp_enthalpy_array)
+    SS304L.energy_density = energy_density_total_enthalpy(SS304L.density, SS304L.specific_enthalpy)
+    SS304L.energy_density_solidus = SS304L.energy_density.evalf(T, SS304L.temperature_solidus)
+    SS304L.energy_density_liquidus = SS304L.energy_density.evalf(T, SS304L.temperature_liquidus)
 
     # Populate temperature_array and energy_density_array
-    SS316L.temperature_array = density_temp_array
-    SS316L.energy_density_temperature_array = u1_temp_array
+    SS304L.temperature_array = density_temp_array
+    SS304L.energy_density_temperature_array = u1_temp_array
 
-    SS316L.energy_density_array = np.array([
-        SS316L.energy_density.evalf(T, temp) for temp in density_temp_array
+    SS304L.energy_density_array = np.array([
+        SS304L.energy_density.evalf(T, temp) for temp in density_temp_array
     ])
 
-    args = (SS316L.temperature_array,
-            SS316L.energy_density_liquidus,
-            SS316L.energy_density_array)
+    args = (SS304L.temperature_array,
+            SS304L.energy_density_liquidus,
+            SS304L.energy_density_array)
 
-    E = SS316L.energy_density.evalf(T, SS316L.temperature_liquidus)
+    E = SS304L.energy_density.evalf(T, SS304L.temperature_liquidus)
     result = prepare_interpolation_arrays(
-        SS316L.temperature_array,
-        SS316L.energy_density_array
+        SS304L.temperature_array,
+        SS304L.energy_density_array
     )
 
     if result["method"] == "double_lookup":
@@ -144,18 +143,18 @@ def create_SS316L(T: Union[float, sp.Symbol]) -> Alloy:
     T_star = interpolate_binary_search(*args)
     print(f"T_star: {T_star}")
 
-    return SS316L
+    return SS304L
 
 
 if __name__ == '__main__':
     Temp = sp.Symbol('T')
-    alloy = create_SS316L(Temp)
+    alloy = create_SS304L(Temp)
 
     # Print the composition of each element in the alloy
     for i in range(len(alloy.composition)):
         print(f"Element {alloy.elements[i]}: {alloy.composition[i]}")
 
-    print("\nTesting SS316L with symbolic temperature:")
+    print("\nTesting SS304L with symbolic temperature:")
     for field in vars(alloy):
         print(f"{field} = {alloy.__getattribute__(field)}")
 
diff --git a/src/pymatlib/data/alloys/SS316L/SS304L.yaml b/src/pymatlib/data/alloys/SS304L/SS304L.yaml
similarity index 92%
rename from src/pymatlib/data/alloys/SS316L/SS304L.yaml
rename to src/pymatlib/data/alloys/SS304L/SS304L.yaml
index c75fead142376d0ab0f99fdcc971a870196b42b5..8af978baa2616dfc4d0d9f52d5511f1f930e7146 100644
--- a/src/pymatlib/data/alloys/SS316L/SS304L.yaml
+++ b/src/pymatlib/data/alloys/SS304L/SS304L.yaml
@@ -133,8 +133,8 @@ properties:
   #OR
   # energy_density: compute
   #OR
-  energy_density:
-    compute: total_enthalpy  # Explicit model selection
+  energy_density: compute
+    #compute: total_enthalpy  # Explicit model selection
   # User can specify either:
   energy_density_temperature_array: (300, 3000, 541)  # int for number of points
   # OR
@@ -142,22 +142,16 @@ properties:
   # save the energy_density and temperature as arrays always.
 
 
-  #density: 7950
+  #density: 7950.
   #OR
-  #density: compute  # computed by thermal expansion coefficient, should be acceptable even if TEC is defined later in the file
-  base_temperature: 2273
+  density: compute  # computed by thermal expansion coefficient, should be acceptable even if TEC is defined later in the file
+  base_temperature: 2273.
   base_density: 6.591878918e3
   #OR
-  density:
-    file: ./304L_Erstarrungsdaten_edited.xlsx
-    temp_col: T (K)
-    prop_col: Density (kg/(m)^3)
 
 
-  heat_conductivity:
-    file: ./304L_Erstarrungsdaten_edited.xlsx
-    temp_col: T (K)
-    prop_col: Thermal conductivity (W/(m*K))-TOTAL-10000.0(K/s)
+
+
 
 
   heat_capacity:
@@ -182,9 +176,9 @@ properties:
     # val: [171401, 0]
 
 
-  # heat_conductivity:
-    # key: [1200, 1800, 2200, 2400]  # temperature values
-    # val: [25, 30, 33, 35]  # corresponding heat_conductivity values
+  heat_conductivity:
+    val: [25, 30, 33, 35]  # corresponding heat_conductivity values
+    key: [25, 30, 33, 35]
 
 
   # heat_capacity:
diff --git a/src/pymatlib/data/alloys/SS316L/__init__.py b/src/pymatlib/data/alloys/SS304L/__init__.py
similarity index 100%
rename from src/pymatlib/data/alloys/SS316L/__init__.py
rename to src/pymatlib/data/alloys/SS304L/__init__.py
diff --git a/src/pymatlib/data/alloys/SS316L/density_temperature.txt b/src/pymatlib/data/alloys/SS304L/density_temperature.txt
similarity index 100%
rename from src/pymatlib/data/alloys/SS316L/density_temperature.txt
rename to src/pymatlib/data/alloys/SS304L/density_temperature.txt
diff --git a/src/pymatlib/data/alloys/SS316L/density_temperature_edited.txt b/src/pymatlib/data/alloys/SS304L/density_temperature_edited.txt
similarity index 100%
rename from src/pymatlib/data/alloys/SS316L/density_temperature_edited.txt
rename to src/pymatlib/data/alloys/SS304L/density_temperature_edited.txt
diff --git a/src/pymatlib/data/alloys/SS316L/heat_capacity_temperature.txt b/src/pymatlib/data/alloys/SS304L/heat_capacity_temperature.txt
similarity index 100%
rename from src/pymatlib/data/alloys/SS316L/heat_capacity_temperature.txt
rename to src/pymatlib/data/alloys/SS304L/heat_capacity_temperature.txt
diff --git a/src/pymatlib/data/alloys/SS316L/heat_capacity_temperature_edited.txt b/src/pymatlib/data/alloys/SS304L/heat_capacity_temperature_edited.txt
similarity index 100%
rename from src/pymatlib/data/alloys/SS316L/heat_capacity_temperature_edited.txt
rename to src/pymatlib/data/alloys/SS304L/heat_capacity_temperature_edited.txt
diff --git a/src/pymatlib/data/alloys/SS316L/heat_conductivity_temperature.txt b/src/pymatlib/data/alloys/SS304L/heat_conductivity_temperature.txt
similarity index 100%
rename from src/pymatlib/data/alloys/SS316L/heat_conductivity_temperature.txt
rename to src/pymatlib/data/alloys/SS304L/heat_conductivity_temperature.txt
diff --git a/tests/cpp/TestArrayContainer.py b/tests/cpp/TestArrayContainer.py
index a20d260637c211345334af2fed0b3be8d708f24d..8fc49760bbba61743ae2cabc84cde4b6a7d3c39f 100644
--- a/tests/cpp/TestArrayContainer.py
+++ b/tests/cpp/TestArrayContainer.py
@@ -21,7 +21,7 @@ with SourceFileGenerator() as sfg:
     custom_container = InterpolationArrayContainer("DoubleLookupTests", np.flip(T_eq), np.flip(E_neq))
     sfg.generate(custom_container)
 
-    yaml_path = files('pymatlib.data.alloys.SS316L').joinpath('SS304L.yaml')
+    yaml_path = files('pymatlib.data.alloys.SS304L').joinpath('SS304L.yaml')
     mat = create_alloy_from_yaml(yaml_path, u.center())
-    arr_container = InterpolationArrayContainer.from_material("SS316L", mat)
+    arr_container = InterpolationArrayContainer.from_material("SS304L", mat)
     sfg.generate(arr_container)
diff --git a/tests/legacy/test_interpolate_functs_perf.py b/tests/legacy/test_interpolate_functs_perf.py
index 4cb35850857fa8e3785bfb5229bf32687dafefbe..793570b3d7fa0f56ffa399b3a1073d77487f3073 100644
--- a/tests/legacy/test_interpolate_functs_perf.py
+++ b/tests/legacy/test_interpolate_functs_perf.py
@@ -97,8 +97,8 @@ def create_alloy(T: Union[float, sp.Symbol]) -> Alloy:
     base_dir = Path(__file__).parent
 
     # Paths to data files using relative paths
-    density_data_file_path = str(base_dir/'..'/'data'/'alloys'/'SS316L'/'density_temperature_edited.txt')
-    heat_capacity_data_file_path = str(base_dir/'..'/'data'/'alloys'/'SS316L'/'heat_capacity_temperature_edited.txt')
+    density_data_file_path = str(base_dir/'..'/'data'/'alloys'/'SS304L'/'density_temperature_edited.txt')
+    heat_capacity_data_file_path = str(base_dir/'..'/'data'/'alloys'/'SS304L'/'heat_capacity_temperature_edited.txt')
 
     # Read temperature and material property data from the files
     density_temp_array, density_array = read_data(density_data_file_path)
@@ -162,7 +162,7 @@ def create_alloy(T: Union[float, sp.Symbol]) -> Alloy:
         raise ValueError(f"Mismatch value. Temperature value should be {alloy.temperature_liquidus}")
 
     E_target_alloy = generate_target_points(float(alloy.energy_density_array[0]), float(alloy.energy_density_array[-1]), 1_000)
-    compare_interpolation_methods(E_target_alloy, T_eq, E_neq, E_eq, inv_delta_E_eq, idx_map, 'SS316L')
+    compare_interpolation_methods(E_target_alloy, T_eq, E_neq, E_eq, inv_delta_E_eq, idx_map, 'SS304L')
 
     def measure_performance(iterations=1):
         all_execution_times = np.zeros(iterations)
diff --git a/tests/python/test_alloy.py b/tests/python/test_alloy.py
index 8477a9517042c229795d9813c2eb5dca02984e6a..cfbb44cfe278a952fa659fe4d5ee29b765025e56 100644
--- a/tests/python/test_alloy.py
+++ b/tests/python/test_alloy.py
@@ -3,7 +3,7 @@ import numpy as np
 import sympy as sp
 from pymatlib.core.alloy import Alloy, AlloyCompositionError, AlloyTemperatureError
 from pymatlib.data.element_data import Ti, Al, V, Fe, Cr, Mn, Ni
-from src.pymatlib.data.alloys.SS316L.SS316L import create_SS316L
+from src.pymatlib.data.alloys.SS304L.SS304L import create_SS304L
 from src.pymatlib.core.typedefs import MaterialProperty
 
 def test_alloy_creation():
@@ -22,9 +22,9 @@ def test_alloy_creation():
         Alloy(elements=[Fe, Cr, Mn, Ni], composition=[0.7, 0.2, 0.05, 0.05], temperature_solidus=1900., temperature_liquidus=1800.)
 
 def test_create_SS316L():
-    """Test the creation and properties of SS316L alloy."""
+    """Test the creation and properties of SS304L alloy."""
     # Test with float temperature input
-    alloy = create_SS316L(1400.0)
+    alloy = create_SS304L(1400.0)
 
     # Check if properties are set and have correct types
     assert hasattr(alloy, 'density')
@@ -40,7 +40,7 @@ def test_create_SS316L():
 
     # Test with symbolic temperature input
     T = sp.Symbol('T')
-    alloy_symbolic = create_SS316L(T)
+    alloy_symbolic = create_SS304L(T)
 
     # Check symbolic properties
     assert alloy_symbolic.density is not None
@@ -55,7 +55,7 @@ def test_create_SS316L():
     assert isinstance(float(alloy.thermal_diffusivity.expr), float)
 
 def test_create_SS316L2():
-    alloy = create_SS316L(1400.0)
+    alloy = create_SS304L(1400.0)
 
     # Check if density exists and has the correct type
     assert hasattr(alloy, 'density')
@@ -70,14 +70,14 @@ def test_alloy_single_element():
 
 def test_alloy_property_modification():
     # Test accessing and modifying individual alloy properties
-    alloy = create_SS316L(1400.0)
+    alloy = create_SS304L(1400.0)
     # assert isinstance(alloy.density, MaterialProperty)
     # Set the density to a MaterialProperty instance with a constant expression
     alloy.density = MaterialProperty(expr=sp.Float(8000.0))
     assert alloy.density.expr == sp.Float(8000.0)
 
 '''def test_create_SS316L_invalid_temperature():
-    # Test creating SS316L alloy with invalid temperature inputs
+    # Test creating SS304L alloy with invalid temperature inputs
     with pytest.raises(ValueError):
         create_SS316L(-100.0)  # Negative temperature
     with pytest.raises(ValueError):
diff --git a/tests/python/test_yaml_config.py b/tests/python/test_yaml_config.py
index d3709938f4a8979fe083d08467fae474c1986405..f121e0c10456047b460f66c5e8de679d910082fb 100644
--- a/tests/python/test_yaml_config.py
+++ b/tests/python/test_yaml_config.py
@@ -14,11 +14,10 @@ T = sp.Symbol('T')
 
 # Get the path to the YAML file
 current_file = Path(__file__)
-yaml_path = current_file.parent.parent.parent / "src" / "pymatlib" / "data" / "alloys" / "SS316L" / "SS304L.yaml"
+yaml_path = current_file.parent.parent.parent / "src" / "pymatlib" / "data" / "alloys" / "SS304L" / "SS304L.yaml"
 
 # Create alloy from YAML
 ss316l = create_alloy_from_yaml(yaml_path, T)
-#ss316l_1 = create_alloy_from_yaml("SS304L_1.yaml", T)
 
 # Test various properties
 print(f"Elements: {ss316l.elements}")
@@ -26,14 +25,16 @@ print(f"Composition: {ss316l.composition}")
 # Print the composition of each element in the alloy
 for i in range(len(ss316l.composition)):
     print(f"Element {ss316l.elements[i]}: Composition {ss316l.composition[i]}")
-print(f"Solidus Temperature: {ss316l.temperature_solidus}")
+
+print(f"\nSolidus Temperature: {ss316l.temperature_solidus}")
 print(f"Liquidus Temperature: {ss316l.temperature_liquidus}")
-print("\nTesting SS316L with symbolic temperature:")
+
+print("\nTesting SS304L with symbolic temperature:")
 for field in vars(ss316l):
     print(f"{field} = {ss316l.__getattribute__(field)}")
 
 # Test computed properties at specific temperature
-test_temp = 1605
+test_temp = 1670
 print(f"\nProperties at {test_temp}K:")
 print(f"Density: {print_property_value(ss316l.density, T, test_temp)}")
 print(f"Specific enthalpy: {print_property_value(ss316l.specific_enthalpy, T, test_temp)}")
@@ -46,4 +47,4 @@ print(f"Latent heat: {ss316l.latent_heat_of_fusion.evalf(T, test_temp)}")
 # Test array generation for energy density
 if hasattr(ss316l, 'energy_density_array'):
     print(f"\nEnergy Density Array Shape: {ss316l.energy_density_array.shape}")
-    print(f"Temperature Array Shape: {ss316l.energy_density_temperature_array.shape}")
+    print(f"Energy Density Temperature Array Shape: {ss316l.energy_density_temperature_array.shape}")