Source code for ogstools.materiallib.core.components

# Copyright (c) 2012-2025, OpenGeoSys Community (http://www.opengeosys.org)
#            Distributed under a Modified BSD License.
#            See accompanying file LICENSE.txt or
#            http://www.opengeosys.org/project/license
#

from pathlib import Path

import yaml  # type: ignore[import]

# from ogstools.definitions import MATERIALS_DIR
import ogstools.definitions as defs

from .component import Component
from .material import Material
from .property import MaterialProperty


[docs] class Components:
[docs] def __init__( self, phase_type: str, gas_component: Material, liquid_component: Material, process: str, Diffusion_coefficient: float | None = None, ): self.phase_type = phase_type self.gas_properties: list[MaterialProperty] = gas_component.properties self.liquid_properties: list[MaterialProperty] = ( liquid_component.properties ) self.process = process self.gas_component = gas_component self.liquid_component = liquid_component if self.phase_type == "AqueousLiquid": gas_role = "Solute" liquid_role = "Solvent" elif self.phase_type == "Gas": gas_role = "Carrier" liquid_role = "Vapour" else: msg = f"Unsupported phase_type: {self.phase_type}" raise ValueError(msg) D = ( Diffusion_coefficient if Diffusion_coefficient is not None else self.get_binary_diffusion_coefficient(self.phase_type) ) self.gas_component_obj = self._create_component( self.gas_component, gas_role, D ) self.liquid_component_obj = self._create_component( self.liquid_component, liquid_role, D )
[docs] def get_binary_diffusion_coefficient(self, phase: str) -> float: """ Retrieves the binary diffusion coefficient D [m²/s] for a specific component pair in either the liquid or gas phase. In the liquid phase, this typically describes a gas (e.g. CO2) diffusing in a solvent like water. In the gas phase, it typically describes a vapor (e.g. H2O) diffusing in a carrier gas like CO₂. Parameters: phase (str): Either "liquid" or "gas". Indicates the phase in which diffusion occurs. Returns: float: Binary diffusion coefficient in [m²/s]. Raises: ValueError: If the component pair is not found. """ if phase == "AqueousLiquid": # Solute (gas component) diffuses in solvent (liquid component) solvent = self.liquid_component.name solute = self.gas_component.name elif phase == "Gas": # Solute (liquid component) evaporates into solvent (gas component) solvent = self.gas_component.name solute = self.liquid_component.name else: msg = f"Invalid phase '{phase}'. Must be 'AqueousLiquid' or 'Gas'." raise ValueError(msg) file_path = Path(defs.MATERIALS_DIR) / "diffusion_coefficients.yml" with file_path.open() as f: data = yaml.safe_load(f) try: return float(data[phase][solvent][solute]) except KeyError: pass try: return float(data[phase][solute][solvent]) except KeyError as err: msg = ( f"No {phase}-phase diffusion coefficient found for the pair " f"'{solvent} / {solute}' in {file_path}" ) raise ValueError(msg) from err
def _create_component( self, material: Material, role: str, D: float ) -> Component: return Component( material, self.phase_type, role, self.process, diffusion_coefficient=D, ) # ----------------------- # Representation # ----------------------- def __repr__(self) -> str: lines = [f"<Components for phase '{self.phase_type}'>"] for comp in [self.gas_component_obj, self.liquid_component_obj]: for line in repr(comp).splitlines(): lines.append(" " + line) return "\n".join(lines)