Source code for ogstools.ogs6py.media
# SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
# SPDX-License-Identifier: BSD-3-Clause
from typing import Any
from lxml import etree as ET
from ogstools.ogs6py import build_tree
from ogstools.property_types import PROPERTY_TYPES
[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]] = {
name: list(spec.parameters) for name, spec in PROPERTY_TYPES.items()
}
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:
medium: ET.Element | None = None
medium_id: str | None = args.get("medium_id")
if "medium_id" not in args:
args["medium_id"] = "0"
if medium_id not in (None, "None"):
medium = self.media.find(f"./medium[@id='{args['medium_id']}']")
else:
_media = self.media.findall("./medium")
if len(_media) == 0:
pass
elif len(_media) > 1:
msg = "Multiple media found but no id provided!"
raise IndexError(msg)
else:
medium = _media[0]
assert (
medium.attrib.get("id", "0") == "0"
), "Expected id='0' when no `medium_id` is given"
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']}]"
)