diff --git a/src/pymatlib/core/models.py b/src/pymatlib/core/models.py index 6f3e60503f58daf78916d695694d52b28a4ebaf6..fd759e237e69ade28056ccc025a8dcd06f0ed727 100644 --- a/src/pymatlib/core/models.py +++ b/src/pymatlib/core/models.py @@ -127,28 +127,93 @@ def thermal_diffusivity_by_heat_conductivity( def specific_enthalpy_sensible( - temperature: Union[float, sp.Symbol], + T: Union[float, sp.Symbol], + temperature_array: np.ndarray, heat_capacity: Union[float, MaterialProperty]) \ -> MaterialProperty: + """ + Calculate specific enthalpy array using heat capacity only. + h(T_i) = h(T_(i-1)) + c_p(T_i)*(T_i - T_(i-1)) + """ + print("Entering specific_enthalpy_sensible") + # Validate temperature array is sorted + if not np.all(temperature_array[:-1] <= temperature_array[1:]): + raise ValueError("Temperature array must be sorted in ascending order for correct enthalpy calculation.") + # print(temperature_array) + print(temperature_array.shape) + # Initialize enthalpy array + enthalpy_array = np.zeros_like(temperature_array) + # Calculate initial enthalpy at the first temperature + T_0 = temperature_array[0] + cp_0 = heat_capacity.evalf(T, T_0) + print(T_0, cp_0) - heat_capacity_expr, sub_assignments \ - = _prepare_material_expressions(heat_capacity) + # Calculate enthalpy at first temperature point + enthalpy_array[0] = cp_0 * T_0 - specific_enthalpy_expr = temperature * heat_capacity_expr - return MaterialProperty(specific_enthalpy_expr, sub_assignments) + # Iterate through temperature points to calculate enthalpy incrementally + for i in range(1, len(temperature_array)): + T_i = temperature_array[i] + T_prev = temperature_array[i-1] + # Evaluate material properties at current temperature + cp_i = heat_capacity.evalf(T, T_i) -def specific_enthalpy_with_latent_heat( - temperature: Union[float, sp.Symbol], - heat_capacity: Union[float, MaterialProperty], - latent_heat: Union[float, MaterialProperty]) \ - -> MaterialProperty: + # Calculate enthalpy increment + sensible_heat = cp_i * (T_i - T_prev) - (heat_capacity_expr, latent_heat_expr), sub_assignments \ - = _prepare_material_expressions(heat_capacity, latent_heat) + # Update enthalpy + enthalpy_array[i] = enthalpy_array[i-1] + sensible_heat - specific_enthalpy_expr = temperature * heat_capacity_expr + latent_heat_expr - return MaterialProperty(specific_enthalpy_expr, sub_assignments) + from pymatlib.core.interpolators import interpolate_property + return interpolate_property(T, temperature_array, enthalpy_array) + + +def specific_enthalpy_with_latent_heat( + T: Union[float, sp.Symbol], + temperature_array: np.ndarray, + heat_capacity: MaterialProperty, + latent_heat: MaterialProperty) -> MaterialProperty: + """ + Calculate specific enthalpy array using heat capacity and latent heat. + h(T_i) = h(T_(i-1)) + c_p(T_i)*(T_i - T_(i-1)) + [L(T_i) - L(T_(i-1))] + """ + print("Entering specific_enthalpy_with_latent_heat") + # Validate temperature array is sorted + if not np.all(temperature_array[:-1] <= temperature_array[1:]): + raise ValueError("Temperature array must be sorted in ascending order for correct enthalpy calculation.") + # print(temperature_array) + print(temperature_array.shape) + # Initialize enthalpy array + enthalpy_array = np.zeros_like(temperature_array) + # Calculate initial enthalpy at the first temperature + T_0 = temperature_array[0] + cp_0 = heat_capacity.evalf(T, T_0) + L_0 = latent_heat.evalf(T, T_0) + print(T_0, cp_0, L_0) + + # Calculate enthalpy at first temperature point + enthalpy_array[0] = cp_0 * T_0 + L_0 + + # Iterate through temperature points to calculate enthalpy incrementally + for i in range(1, len(temperature_array)): + T_i = temperature_array[i] + T_prev = temperature_array[i-1] + + # Evaluate material properties at current temperature + cp_i = heat_capacity.evalf(T, T_i) + L_i = latent_heat.evalf(T, T_i) + L_prev = latent_heat.evalf(T, T_prev) + + # Calculate enthalpy increment + sensible_heat = cp_i * (T_i - T_prev) + latent_heat_change = L_i - L_prev + + # Update enthalpy + enthalpy_array[i] = enthalpy_array[i-1] + sensible_heat + latent_heat_change + + from pymatlib.core.interpolators import interpolate_property + return interpolate_property(T, temperature_array, enthalpy_array) def energy_density( diff --git a/src/pymatlib/core/yaml_parser.py b/src/pymatlib/core/yaml_parser.py index dccaa12a742b7da99f6c0ecab52d86fddf520e37..6f18b2b8c7569de98d608c03f553bdf196849014 100644 --- a/src/pymatlib/core/yaml_parser.py +++ b/src/pymatlib/core/yaml_parser.py @@ -70,7 +70,7 @@ class MaterialConfigParser: self.base_dir = Path(yaml_path).parent self.config: Dict[str, Any] = self._load_yaml() self._validate_config() - self._process_temperature_range(self.config['temperature_range']) + self.temperature_array = self._process_temperature_range(self.config['temperature_range']) def _load_yaml(self) -> Dict[str, Any]: """Load and parse YAML file. @@ -193,8 +193,10 @@ class MaterialConfigParser: temperature_array = self._process_float_step(start, end, step) else: temperature_array = self._process_int_step(start, end, int(step)) - self.temperature_array = temperature_array # Store the temperature array - # print(self.temperature_array) + # Ensure temperature array is in ascending order + if not np.all(np.diff(temperature_array) >= 0): + print("Flipping temperature array") + temperature_array = np.flip(temperature_array) return temperature_array except ValueError as e: raise ValueError(f"Invalid temperature array definition \n -> {e}") @@ -237,7 +239,6 @@ class MaterialConfigParser: 'dynamic_viscosity', 'kinematic_viscosity', 'thermal_diffusivity', 'surface_tension'} NON_NEGATIVE_PROPERTIES = {'latent_heat_of_fusion', 'latent_heat_of_vaporization', 'energy_density',} - # 'energy_density_solidus', 'energy_density_liquidus'} # Property-specific range constraints PROPERTY_RANGES = { @@ -845,8 +846,8 @@ class MaterialConfigParser: if prop_name == 'energy_density' and isinstance(T, sp.Symbol): self._handle_energy_density(alloy, material_property, T) - @staticmethod - def _get_computation_methods(alloy: Alloy, T: Union[float, sp.Symbol]): + # @staticmethod + def _get_computation_methods(self, alloy: Alloy, T: Union[float, sp.Symbol]): """ Get the computation methods for various properties of the alloy. Args: @@ -874,10 +875,12 @@ class MaterialConfigParser: 'specific_enthalpy': { 'default': lambda: specific_enthalpy_sensible( T, + self.temperature_array, alloy.heat_capacity ), 'latent_heat_based': lambda: specific_enthalpy_with_latent_heat( T, + self.temperature_array, alloy.heat_capacity, alloy.latent_heat_of_fusion ) @@ -974,5 +977,5 @@ def create_alloy_from_yaml(yaml_path: Union[str, Path], T: Union[float, sp.Symbo """ parser = MaterialConfigParser(yaml_path) alloy = parser.create_alloy(T) - temp_array = parser.temperature_array - return alloy, temp_array + temperature_array = parser.temperature_array + return alloy, temperature_array diff --git a/src/pymatlib/data/alloys/SS304L/304L_Erstarrungsdaten_edited.xlsx b/src/pymatlib/data/alloys/SS304L/304L_Erstarrungsdaten_edited.xlsx index ede7ba8d4a1b3d31f6466c020b4eb1747cdc1bd2..d5e3b4fb7b10d59dc4447801a1f47c9aa6827b54 100644 Binary files a/src/pymatlib/data/alloys/SS304L/304L_Erstarrungsdaten_edited.xlsx and b/src/pymatlib/data/alloys/SS304L/304L_Erstarrungsdaten_edited.xlsx differ diff --git a/src/pymatlib/data/alloys/SS304L/SS304L.yaml b/src/pymatlib/data/alloys/SS304L/SS304L.yaml index 19bb2124f4d67cf18427080b518748acc6848a78..d417e8a9f1ee737c9397044923c3bc6876e0d23b 100644 --- a/src/pymatlib/data/alloys/SS304L/SS304L.yaml +++ b/src/pymatlib/data/alloys/SS304L/SS304L.yaml @@ -173,35 +173,35 @@ properties: thermal_expansion_coefficient: 16.3e-6 specific_enthalpy: - file: ./304L_Erstarrungsdaten_edited.xlsx - temp_col: T (K) - prop_col: Enthalpy (J/kg) + compute: default + #OR + # compute: latent_heat_based + # latent_heat_of_fusion: + # file: ./304L_Erstarrungsdaten_edited.xlsx + # temp_col: T (K) + # prop_col: Latent heat (J/Kg) + #OR latent_heat_of_fusion: - file: ./304L_Erstarrungsdaten_edited.xlsx - temp_col: T (K) - prop_col: Latent heat (J/Kg) - #OR - # latent_heat_of_fusion: - # key: [solidus_temperature, liquidus_temperature] - # val: [171401, 0] + key: [solidus_temperature, liquidus_temperature] + val: [0, 171401] - # heat_conductivity: + # heat_conductivity: # key: [1200, 1800, 2200, 2400] # temperature values # val: [25, 30, 33, 35] # corresponding heat_conductivity values - # heat_capacity: + # heat_capacity: # key: [solidus_temperature, liquidus_temperature] # val: [600, 800] - #OR - # heat_capacity: + #OR + # heat_capacity: # key: (1000, 200) # generates equidistant values starting 1000 with an increment of 200 until the length of val # [1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3200] # val: [580, 590, 600, 600, 600, 610, 620, 630, 660, 700, 750, 750] - #OR - # heat_capacity: + #OR + # heat_capacity: # key: [1000, 1200, 1400, 1600, ...] # val: [580, 590, 600, 600, 600, 610, 620, 630, 660, 700, 750, 780, 789, 799, 800, 800, 800, ...] #OR