Source code for ogstools.ogs6py.media

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

"""
from typing import Any

from lxml import etree as ET

from ogstools.ogs6py import build_tree


[docs] class Media(build_tree.BuildTree): """ Class for defining a media material properties." """
[docs] def __init__(self, tree: ET.ElementTree) -> None: self.tree = tree self.root = self.tree.getroot() self.media = self.populate_tree(self.root, "media", overwrite=True) self.properties: dict[str, list[str]] = { "AverageMolarMass": [], "BishopsSaturationCutoff": ["cutoff_value"], "BishopsPowerLaw": ["exponent"], "CapillaryPressureRegularizedVanGenuchten": [ "exponent", "p_b", "residual_gas_saturation", "residual_liquid_saturation", ], "CapillaryPressureVanGenuchten": [ "exponent", "maximum_capillary_pressurep_b", "residual_gas_saturation", "residual_liquid_saturation", ], "ClausiusClapeyron": [ "critical_pressure", "critical_temperature", "reference_pressure", "reference_temperature", "triple_pressure", "triple_temperature", ], "Constant": ["value"], "Curve": ["curve", "independent_variable"], "DupuitPermeability": ["parameter_name"], "EffectiveThermalConductivityPorosityMixing": [], "EmbeddedFracturePermeability": [ "intrinsic_permeability", "initial_aperture", "mean_frac_distance", "threshold_strain", "fracture_normal", "fracture_rotation_xy", "fracture_rotation_yz", ], "Function": ["value"], "Exponential": ["offset", "reference_value"], "GasPressureDependentPermeability": [ "initial_permeability", "a1", "a2", "pressure_threshold", "minimum_permeability", "maximum_permeability", ], "IdealGasLaw": [], "IdealGasLawBinaryMixture": [], "KozenyCarmanModel": ["intitial_permeability", "initial_prosity"], "Linear": ["reference_value"], "LinearSaturationSwellingStress": [ "coefficient", "reference_saturation", ], "LinearWaterVapourLatentHeat": [], "OrthotropicEmbeddedFracturePermeability": [ "intrinsic_permeability", "mean_frac_distances", "threshold_strains", "fracture_normals", "fracture_rotation_xy", "fracture_rotation_yz", "jacobian_factor", ], "Parameter": ["parameter_name"], "PermeabilityMohrCoulombFailureIndexModel": [ "cohesion", "fitting_factor", "friction_angle", "initial_ppermeability", "maximum_permeability", "reference_permeability", "tensile_strength_parameter", ], "PermeabilityOrthotropicPowerLaw": [ "exponents", "intrinsic_permeabilities", ], "PorosityFromMassBalance": [ "initial_porosity", "maximal_porosity", "minimal_porosity", ], "RelPermBrooksCorey": [ "lambda", "min_relative_permeabilityresidual_gas_saturation", "residual_liquid_saturation", ], "RelPermBrooksCoreyNonwettingPhase": [ "lambda", "min_relative_permeabilityresidual_gas_saturation", "residual_liquid_saturation", ], "RelPermLiakopoulos": [], "RelativePermeabilityNonWettingVanGenuchten": [ "exponent", "minimum_relative_permeability", "residual_gas_saturation", "residual_liquid_saturation", ], "RelativePermeabilityUdell": [ "min_relative_permeability", "residual_gas_saturation", "residual_liquid_saturation", ], "RelativePermeabilityUdellNonwettingPhase": [ "min_relative_permeability", "residual_gas_saturation", "residual_liquid_saturation", ], "RelativePermeabilityVanGenuchten": [ "exponent", "minimum_relative_permeability_liquid", "residual_gas_saturation", "residual_liquid_saturation", ], "SaturationBrooksCorey": [ "entry_pressure", "lambda", "residual_gas_saturation", "residual_liquid_saturation", ], "SaturationDependentSwelling": [ "exponents", "lower_saturation_limit", "swelling_pressures", "upper_saturation_limit", ], "SaturationDependentThermalConductivity": ["dry", "wet"], "SaturationExponential": [ "exponent", "maximum_capillary_pressure", "residual_gas_saturation", "residual_liquid_saturation", ], "SaturationLiakopoulos": [], "SaturationWeightedThermalConductivity": [ "mean_type", "dry_thermal_conductivity", "wet_thermal_conductivity", ], "SaturationVanGenuchten": [ "exponent", "p_b", "residual_gas_saturation", "residual_liquid_saturation", ], "SoilThermalConductivitySomerton": [ "dry_thermal_conductivity", "wet_thermal_conductivity", ], "StrainDependentPermeability": [ "initial_permeability", "b1", "b2", "b3", "minimum_permeability", "maximum_permeability", ], "TemperatureDependentDiffusion": [ "activation_energy", "reference_diffusion", "reference_temperature", ], "TransportPorosityFromMassBalance": [ "initial_porosity", "maximal_porosity", "minimal_porosity", ], "VapourDiffusionFEBEX": ["tortuosity"], "VapourDiffusionPMQ": [], "VermaPruessModel": [ "critical_porosity", "exponent", "initial_permeability", "initial_porosity", ], "WaterVapourDensity": [], "WaterDensityIAPWSIF97Region1": [], "WaterVapourLatentHeatWithCriticalTemperature": [], }
def _generate_generic_property( self, property_: ET.Element, args: dict[str, Any] ) -> None: for parameter in self.properties[args["type"]]: self.populate_tree(property_, parameter, text=args[parameter]) def _generate_linear_property( self, property_: ET.Element, args: dict[str, Any] ) -> None: for parameter in self.properties[args["type"]]: self.populate_tree(property_, parameter, text=args[parameter]) for var, param in args["independent_variables"].items(): ind_var = self.populate_tree(property_, "independent_variable") self.populate_tree(ind_var, "variable_name", text=var) attributes = ["reference_condition", "slope"] for attrib in attributes: self.populate_tree(ind_var, attrib, text=str(param[attrib])) def _generate_function_property( self, property_: ET.Element, args: dict[str, Any] ) -> None: for parameter in self.properties[args["type"]]: value = self.populate_tree( property_, parameter, text=args[parameter] ) self.populate_tree(value, "expression", text=args["expression"]) for dvar in args["dvalues"]: dvalue = self.populate_tree(property_, "dvalue") self.populate_tree(dvalue, "variable_name", text=dvar) self.populate_tree( dvalue, "expression", text=args["dvalues"][dvar]["expression"] ) def _generate_exponential_property( self, property_: ET.Element, args: dict[str, Any] ) -> None: for parameter in self.properties[args["type"]]: self.populate_tree(property_, parameter, text=args[parameter]) exponent = self.populate_tree(property_, "exponent") self.populate_tree( exponent, "variable_name", text=args["exponent"]["variable_name"] ) attributes = ["reference_condition", "factor"] for attrib in attributes: self.populate_tree( exponent, attrib, text=str(args["exponent"][attrib]) ) def _build_mpl_tree(self, args: dict) -> ET.Element: if "medium_id" not in args: args["medium_id"] = "0" medium = None for entry in self.media.findall("./medium"): if entry.get("id") == args["medium_id"]: medium = entry if medium is None: medium = self.populate_tree( self.media, "medium", attr={"id": args["medium_id"]} ) if "phase_type" in args: phases = self.get_child_tag(medium, "phases") if phases is None: phases = self.populate_tree(medium, "phases") phase = self.get_child_tag_for_type( phases, "phase", args["phase_type"] ) if phase is None: phase = self.populate_tree(phases, "phase") self.populate_tree(phase, "type", text=args["phase_type"]) if "component_name" in args: components = self.populate_tree(phase, "components") component = self.populate_tree(components, "component") self.populate_tree( component, "name", text=args["component_name"] ) properties = self.populate_tree(component, "properties") else: properties = self.populate_tree(phase, "properties") else: if "component_name" in args: components = self.get_child_tag(phase, "components") if components is None: components = self.populate_tree(phase, "components") component = self.get_child_tag_for_type( components, "component", args["component_name"], subtag="name", ) if component is None: component = self.populate_tree(components, "component") self.populate_tree( component, "name", text=args["component_name"] ) properties = self.populate_tree( component, "properties", overwrite=True ) else: properties = self.get_child_tag(phase, "properties") else: properties = self.get_child_tag(medium, "properties") if properties is None: properties = self.populate_tree(medium, "properties") return properties
[docs] def add_property(self, **args: Any) -> None: """ Adds a property to medium/phase. Parameters ---------- medium_id : `int` or `str` phase_type : `str` optional component_name : `str` optional name : `str` type : `str` value : `float` or `str` exponent : `float` or `str` cutoff_value : `float` or `str` independent_variable : `str` reference_condition : `float` or `str` reference_value : `float` or `str` slope : `float` or `str` parameter_name : `str` """ self._convertargs(args) properties = self._build_mpl_tree(args) property_ = self.populate_tree(properties, "property") base_property_param = ["name", "type"] for param in base_property_param: self.populate_tree(property_, param, text=args[param]) try: if args["type"] == "Linear": self._generate_linear_property(property_, args) elif args["type"] == "Exponential": self._generate_exponential_property(property_, args) elif args["type"] == "Function": self._generate_function_property(property_, args) else: self._generate_generic_property(property_, args) except KeyError: print("Material property parameters incomplete for") if "phase_type" in args: print( f"Medium {args['medium_id']}->{args['phase_type']}->{args['name']}[{args['type']}]" ) else: print( f"Medium {args['medium_id']}->{args['name']}[{args['type']}]" )