"""
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 __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ogstools.ogs6py import Project
from collections.abc import Generator
from dataclasses import dataclass, field
from typing import Any
from lxml import etree as ET
[docs]
@dataclass
class Value:
"""Class to hold property values."""
medium: str
value: float | None
[docs]
@dataclass
class Property:
"""Class to hold properties."""
title: str
symbol: str
unit: str
value: list[Value] = field(default_factory=list)
def _dict(self) -> dict[str, Any]:
a: dict[str, Any] = {
"title": self.title,
"symbol": self.symbol,
"unit": self.unit,
}
for d in self.value:
a[d.medium] = d.value
return a
[docs]
@dataclass
class PropertySet:
"""Class to hold a set of properties."""
property: list[Property] = field(default_factory=list)
def __len__(self) -> int:
"""Number of time steps"""
return len(self.property)
def __iter__(self) -> Generator:
for v in self.property:
yield v._dict()
property_dict = {
"Solid": {
"density": {
"title": "Solid density",
"symbol": "$\\rho_\\text{s}$",
"unit": "kg m$^{-3}$",
},
"specific_heat_capacity": {
"title": "Specific heat capacity",
"symbol": "$c_\\text{s}$",
"unit": "J kg$^{-1}$ K$^{-1}$",
},
"thermal_expansivity": {
"title": "Thermal expansivity",
"symbol": "$a_s$",
"unit": "K$^{-1}$",
},
"youngs_modulus": {
"title": "Young's modulus",
"symbol": "$E$",
"unit": "Pa",
},
"poissons_ratio": {
"title": "Poisson's ratio",
"symbol": "$\\nu$",
"unit": "1",
},
},
"Medium": {
"porosity": {"title": "Porosity", "symbol": r"$\phi$", "unit": "1"},
"biot_coefficient": {
"title": "Biot-Willis coefficient",
"symbol": "$\\alpha_\\mathrm{B}$",
"unit": "1",
},
"permeability": {
"title": "Intrinsic permeability",
"symbol": "$k$",
"unit": "m$^2$",
},
"thermal_conductivity": {
"title": "Thermal conductivity",
"symbol": r"$\lambda$",
"unit": "W m$^{-1}$ K$^{-1}$",
},
"vgsat_residual_liquid_saturation": {
"title": "Saturation: Van Genuchten, \\\\ residual liquid saturation",
"symbol": "$S^r_\\text{L}$",
"unit": "1",
},
"vgsat_residual_gas_saturation": {
"title": "Saturation: Van Genuchten, \\\\ residual gas saturation ",
"symbol": "$S^r_\\text{g}$",
"unit": "1",
},
"vgsat_exponent": {
"title": "Saturation: Van Genuchten, \\\\ exponent",
"symbol": "$m$",
"unit": "1",
},
"vgsat_p_b": {
"title": "Saturation: Van Genuchten, \\\\ entry pressure",
"symbol": "$p_b$",
"unit": "Pa",
},
"vgrelperm_residual_liquid_saturation": {
"title": "Relative permeability: Van Genuchten, \\\\ residual liquid saturation ",
"symbol": "$S^r_\\text{L}$",
"unit": "1",
},
"vgrelperm_residual_gas_saturation": {
"title": "Relative permeability: Van Genuchten, \\\\ residual gas saturation ",
"symbol": "$S^r_\\text{g}$",
"unit": "1",
},
"vgrelperm_exponent": {
"title": "Relative permeability: Van Genuchten, \\\\ exponent",
"symbol": "$m$",
"unit": "1",
},
"vgrelperm_minimum_relative_permeability_liquid": {
"title": "Relative permeability: Van Genuchten, \\\\ minimmum relative permeability",
"symbol": "$k^\\text{min}_r$",
"unit": "1",
},
},
"AqueousLiquid": {
"viscosity": {
"title": "Liquid phase viscosity",
"symbol": r"$\mu_\mathrm{LR}$",
"unit": "Pa s",
},
"density": {
"title": "Liquid phase density",
"symbol": "$\\rho_\\mathrm{LR}$",
"unit": "kg m$^{-3}$",
},
"specific_heat_capacity": {
"title": "Liquid specific heat capacity",
"symbol": "$c_\\text{LR}$",
"unit": "J kg$^{-1}$ K$^{-1}$",
},
},
}
location_pointer = {
"Solid": "phases/phase[type='Solid']/",
"Medium": "",
"AqueousLiquid": "phases/phase[type='AqueousLiquid']/",
}
def _expand_tensors(
obj: Project,
numofmedia: int,
multidim_prop: dict[Any, Any],
root: ET.Element,
location: str,
) -> None:
for medium_id in range(numofmedia):
medium = obj._get_medium_pointer(root, medium_id)
const_props = medium.findall(
f"./{location_pointer[location]}properties/property[type='Constant']/value"
)
tobedeleted = []
for prop in const_props:
proplist = prop.text.split(" ")
tags = prop.getparent().getchildren()
for tag in tags:
if tag.tag == "name":
name = tag.text
multidim_prop[medium_id][name] = len(proplist)
if multidim_prop[medium_id][name] > 1:
properties_level = prop.getparent().getparent()
tobedeleted.append(prop.getparent())
taglist = ["name", "type", "value"]
for i in range(multidim_prop[medium_id][name]):
textlist = [f"{name}{i}", "Constant", f"{proplist[i]}"]
elmnt = ET.SubElement(properties_level, "property")
for j, tag in enumerate(taglist):
subelmnt = ET.SubElement(elmnt, tag)
if textlist[j] is not None:
subelmnt.text = str(textlist[j])
for element in tobedeleted:
element.getparent().remove(element)
def _expand_van_genuchten(
obj: Project, numofmedia: int, root: ET.Element, location: str
) -> None:
for medium_id in range(numofmedia):
medium = obj._get_medium_pointer(root, medium_id)
sat_vg_props = medium.findall(
f"./{location_pointer[location]}properties/property[type='SaturationVanGenuchten']"
)
relperm_vg_props = medium.findall(
f"./{location_pointer[location]}properties/property[type='RelativePermeabilityVanGenuchten']"
)
vg_properties = [sat_vg_props, relperm_vg_props]
tobedeleted = []
for vg_property in vg_properties:
for prop in vg_property:
proplist = prop.getchildren()
const_taglist = ["name", "type", "value"]
prefix = ""
for subprop in proplist:
if "SaturationVanGenuchten" in subprop.text:
prefix = "vgsat_"
elif "RelativePermeabilityVanGenuchten" in subprop.text:
prefix = "vgrelperm_"
for subprop in proplist:
if subprop.tag not in ["name", "type"]:
const_textlist = [
prefix + subprop.tag,
"Constant",
subprop.text,
]
elmnt = ET.SubElement(prop.getparent(), "property")
for i, tag in enumerate(const_taglist):
subelmnt = ET.SubElement(elmnt, tag)
if const_textlist[i] is not None:
subelmnt.text = str(const_textlist[i])
tobedeleted.append(prop)
for element in tobedeleted:
element.getparent().remove(element)