From a23b6cb13ae7f0e27f07f6b283b2460969252265 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 16:45:13 +0200 Subject: [PATCH 01/20] restore to state from previous PR --- .../derived_quantities/average_surface.py | 29 ++++++- .../derived_quantities/average_volume.py | 30 ++++++- .../derived_quantities/derived_quantities.py | 12 ++- .../derived_quantities/derived_quantity.py | 30 ++++--- .../derived_quantities/hydrogen_flux.py | 35 +++++++- .../derived_quantities/maximum_surface.py | 38 +++++++-- .../derived_quantities/maximum_volume.py | 34 +++++++- .../derived_quantities/minimum_surface.py | 38 +++++++-- .../derived_quantities/minimum_volume.py | 34 +++++++- .../exports/derived_quantities/point_value.py | 33 ++++++-- .../derived_quantities/surface_flux.py | 79 ++++++++++++++++--- .../derived_quantities/thermal_flux.py | 35 ++++++++ .../derived_quantities/total_surface.py | 48 ++++++++++- .../derived_quantities/total_volume.py | 48 ++++++++++- festim/exports/exports.py | 2 +- .../test_derived_quantities.py | 60 +++++++++++++- .../test_hydrogen_flux.py | 23 ++++++ .../test_surface_flux.py | 21 +++++ .../test_thermal_flux.py | 24 ++++++ .../test_total_surface.py | 21 +++++ .../test_total_volume.py | 21 +++++ .../test_derived_quantities/tools.py | 13 +++ 22 files changed, 648 insertions(+), 60 deletions(-) create mode 100644 test/unit/test_exports/test_derived_quantities/tools.py diff --git a/festim/exports/derived_quantities/average_surface.py b/festim/exports/derived_quantities/average_surface.py index 32007dcb4..cc0dd42dd 100644 --- a/festim/exports/derived_quantities/average_surface.py +++ b/festim/exports/derived_quantities/average_surface.py @@ -3,9 +3,36 @@ class AverageSurface(SurfaceQuantity): + """ + Computes the average value of a field on a given surface + int( f dx) / int (1 * dx) + Args: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + Attributes: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + show_units (bool): show the units in the title in the derived quantities + file + function (dolfin.function.function.Function): the solution function of + the field + Notes: + Units are in H/m3 for hydrogen concentration and K for temperature + """ + def __init__(self, field, surface) -> None: super().__init__(field=field, surface=surface) - self.title = "Average {} surface {}".format(self.field, self.surface) + + @property + def title(self): + quantity_title = f"Average {self.field} surface {self.surface}" + if self.show_units: + if self.field == "T": + return quantity_title + " (K)" + else: + return quantity_title + " (H m-3)" + else: + return quantity_title def compute(self): return f.assemble(self.function * self.ds(self.surface)) / f.assemble( diff --git a/festim/exports/derived_quantities/average_volume.py b/festim/exports/derived_quantities/average_volume.py index 49372e721..2d7fb87e0 100644 --- a/festim/exports/derived_quantities/average_volume.py +++ b/festim/exports/derived_quantities/average_volume.py @@ -3,9 +3,35 @@ class AverageVolume(VolumeQuantity): + """ + Computes the average value of a field in a given volume + Args: + field (str, int): the field ("solute", 0, 1, "T", "retention") + volume (int): the volume id + Attributes: + field (str, int): the field ("solute", 0, 1, "T", "retention") + volume (int): the volume id + show_units (bool): show the units in the title in the derived quantities + file + function (dolfin.function.function.Function): the solution function of + the field + Notes: + Units are in H/m3 for hydrogen concentration and K for temperature + """ + def __init__(self, field, volume: int) -> None: - super().__init__(field, volume) - self.title = "Average {} volume {}".format(self.field, self.volume) + super().__init__(field=field, volume=volume) + + @property + def title(self): + quantity_title = f"Average {self.field} volume {self.volume}" + if self.show_units: + if self.field == "T": + return quantity_title + " (K)" + else: + return quantity_title + " (H m-3)" + else: + return quantity_title def compute(self): return f.assemble(self.function * self.dx(self.volume)) / f.assemble( diff --git a/festim/exports/derived_quantities/derived_quantities.py b/festim/exports/derived_quantities/derived_quantities.py index 0cb0e108d..3cef88ad9 100644 --- a/festim/exports/derived_quantities/derived_quantities.py +++ b/festim/exports/derived_quantities/derived_quantities.py @@ -23,6 +23,8 @@ class DerivedQuantities(list): nb_iterations_between_exports (int, optional): number of iterations between each export. If None, the file will be exported at the last timestep. Defaults to None. + show_units (bool, optional): will show the units of each + derived quantity in the title in export """ def __init__( @@ -31,6 +33,7 @@ def __init__( filename: str = None, nb_iterations_between_compute: int = 1, nb_iterations_between_exports: int = None, + show_units=False, ) -> None: # checks that input is list if len(args) == 0: @@ -43,8 +46,9 @@ def __init__( self.filename = filename self.nb_iterations_between_compute = nb_iterations_between_compute self.nb_iterations_between_exports = nb_iterations_between_exports + self.show_units = show_units - self.data = [self.make_header()] + self.data = [] self.t = [] @property @@ -108,6 +112,7 @@ def filename(self, value): def make_header(self): header = ["t(s)"] for quantity in self: + quantity.show_units = self.show_units header.append(quantity.title) return header @@ -139,6 +144,11 @@ def compute(self, t): value = quantity.compute(self.volume_markers) else: value = quantity.compute() + + # check if first time writing data + if len(self.data) == 0: + self.data = [self.make_header()] + quantity.data.append(value) quantity.t.append(t) row.append(value) diff --git a/festim/exports/derived_quantities/derived_quantity.py b/festim/exports/derived_quantities/derived_quantity.py index 113ac26ba..489ab3fa6 100644 --- a/festim/exports/derived_quantities/derived_quantity.py +++ b/festim/exports/derived_quantities/derived_quantity.py @@ -3,6 +3,8 @@ class DerivedQuantity(Export): """ + Parent class of all derived quantities + Args: field (str, int): the field ("solute", 0, 1, "T", "retention") """ @@ -18,16 +20,19 @@ def __init__(self, field) -> None: self.Q = None self.data = [] self.t = [] + self.show_units = False class VolumeQuantity(DerivedQuantity): - def __init__(self, field: str or int, volume: int) -> None: - """DerivedQuantity relative to a volume + """DerivedQuantity relative to a volume + + Args: + field (str, int): the field ("solute", 0, 1, "T", "retention") + volume (int): the volume id - Args: - field (str, int): the field ("solute", 0, 1, "T", "retention") - volume (int): the volume id - """ + """ + + def __init__(self, field: str or int, volume: int) -> None: super().__init__(field) self.volume = volume @@ -44,13 +49,16 @@ def volume(self, value): class SurfaceQuantity(DerivedQuantity): + """DerivedQuantity relative to a surface + + Args: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + + """ + def __init__(self, field: str or int, surface: int) -> None: - """DerivedQuantity relative to a surface - Args: - field (str, int): the field ("solute", 0, 1, "T", "retention") - surface (int): the surface id - """ super().__init__(field) self.surface = surface diff --git a/festim/exports/derived_quantities/hydrogen_flux.py b/festim/exports/derived_quantities/hydrogen_flux.py index 09f6b9d70..e81370ab8 100644 --- a/festim/exports/derived_quantities/hydrogen_flux.py +++ b/festim/exports/derived_quantities/hydrogen_flux.py @@ -2,7 +2,40 @@ class HydrogenFlux(SurfaceFlux): - """Equivalent to SurfaceFlux("solute", ...)""" + """ + Computes the surface flux of hydrogen at a given surface + + Args: + surface (int): the surface id + + Attribtutes + field (str, int): the hydrogen solute field + surface (int): the surface id + show_units (bool): show the units in the title in the derived quantities + file + title (str): the title of the derived quantity + function (dolfin.function.function.Function): the solution function of + the hydrogen solute field + + Notes: + units are in H/m2/s in 1D, H/m/s in 2D and H/s in 3D domains + + """ def __init__(self, surface) -> None: super().__init__(field="solute", surface=surface) + + @property + def title(self): + quantity_title = f"Flux surface {self.surface}: {self.field}" + if self.show_units: + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if dim == 1: + return quantity_title + " (H m-2 s-1)" + if dim == 2: + return quantity_title + " (H m-1 s-1)" + if dim == 3: + return quantity_title + " (H s-1)" + else: + return quantity_title diff --git a/festim/exports/derived_quantities/maximum_surface.py b/festim/exports/derived_quantities/maximum_surface.py index 35eab5f16..54726c87e 100644 --- a/festim/exports/derived_quantities/maximum_surface.py +++ b/festim/exports/derived_quantities/maximum_surface.py @@ -1,20 +1,42 @@ -from festim import DerivedQuantity +from festim import SurfaceQuantity import fenics as f import numpy as np -class MaximumSurface(DerivedQuantity): +class MaximumSurface(SurfaceQuantity): """ + Computes the maximum value of a field on a given surface + Args: - field (str): the field from which the maximum - is computed (ex: "solute", "retention", "T"...) - surface (int): the surface id where the maximum is computed + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + + Attributes: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + show_units (bool): show the units in the title in the derived quantities + file + function (dolfin.function.function.Function): the solution function of + the field + + Notes: + Units are in H/m3 for hydrogen concentration and K for temperature + """ def __init__(self, field, surface) -> None: - super().__init__(field) - self.surface = surface - self.title = "Maximum {} surface {}".format(self.field, self.surface) + super().__init__(field=field, surface=surface) + + @property + def title(self): + quantity_title = f"Maximum {self.field} surface {self.surface}" + if self.show_units: + if self.field == "T": + return quantity_title + " (K)" + else: + return quantity_title + " (H m-3)" + else: + return quantity_title def compute(self, surface_markers): """Maximum of f over subdomains facets marked with self.surface""" diff --git a/festim/exports/derived_quantities/maximum_volume.py b/festim/exports/derived_quantities/maximum_volume.py index 1c7c66d75..315c5a79a 100644 --- a/festim/exports/derived_quantities/maximum_volume.py +++ b/festim/exports/derived_quantities/maximum_volume.py @@ -4,9 +4,39 @@ class MaximumVolume(VolumeQuantity): + """ + Computes the maximum value in a field in a given volume + + Args: + field (str, int): the field ("solute", 0, 1, "T", "retention") + volume (int): the volume id + + Attributes: + field (str, int): the field ("solute", 0, 1, "T", "retention") + volume (int): the volume id + show_units (bool): show the units in the title in the derived quantities + file + function (dolfin.function.function.Function): the solution function for + the field + + notes: + Units are in H/m3 for hydrogen concentration and K for temperature + + """ + def __init__(self, field, volume) -> None: - super().__init__(field, volume=volume) - self.title = "Maximum {} volume {}".format(self.field, self.volume) + super().__init__(field=field, volume=volume) + + @property + def title(self): + quantity_title = f"Maximum {self.field} volume {self.volume}" + if self.show_units: + if self.field == "T": + return quantity_title + " (K)" + else: + return quantity_title + " (H m-3)" + else: + return quantity_title def compute(self, volume_markers): """Minimum of f over subdomains cells marked with self.volume""" diff --git a/festim/exports/derived_quantities/minimum_surface.py b/festim/exports/derived_quantities/minimum_surface.py index 2ea9c7bc5..6da9f6b16 100644 --- a/festim/exports/derived_quantities/minimum_surface.py +++ b/festim/exports/derived_quantities/minimum_surface.py @@ -1,20 +1,42 @@ -from festim import DerivedQuantity +from festim import SurfaceQuantity import fenics as f import numpy as np -class MinimumSurface(DerivedQuantity): +class MinimumSurface(SurfaceQuantity): """ + Computes the minimum value of a field on a given surface + Args: - field (str): the field from which the minimum - is computed (ex: "solute", "retention", "T"...) - surface (int): the surface id where the minimum is computed + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + + Attributes: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + show_units (bool): show the units in the title in the derived quantities + file + function (dolfin.function.function.Function): the solution function of + the field + + Notes: + Units are in H/m3 for hydrogen concentration and K for temperature + """ def __init__(self, field, surface) -> None: - super().__init__(field) - self.surface = surface - self.title = "Minimum {} surface {}".format(self.field, self.surface) + super().__init__(field=field, surface=surface) + + @property + def title(self): + quantity_title = f"Minimum {self.field} surface {self.surface}" + if self.show_units: + if self.field == "T": + return quantity_title + " (K)" + else: + return quantity_title + " (H m-3)" + else: + return quantity_title def compute(self, surface_markers): """Minimum of f over subdomains facets marked with self.surface""" diff --git a/festim/exports/derived_quantities/minimum_volume.py b/festim/exports/derived_quantities/minimum_volume.py index 02b064789..36cd4c01e 100644 --- a/festim/exports/derived_quantities/minimum_volume.py +++ b/festim/exports/derived_quantities/minimum_volume.py @@ -4,9 +4,39 @@ class MinimumVolume(VolumeQuantity): + """ + Computes the minimum value in a field in a given volume + + Args: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + + Attributes: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + show_units (bool): show the units in the title in the derived quantities + file + function (dolfin.function.function.Function): the solution function for + the field + + notes: + Units are in H/m3 for hydrogen concentration and K for temperature + + """ + def __init__(self, field, volume) -> None: - super().__init__(field, volume=volume) - self.title = "Minimum {} volume {}".format(self.field, self.volume) + super().__init__(field=field, volume=volume) + + @property + def title(self): + quantity_title = f"Minimum {self.field} volume {self.volume}" + if self.show_units: + if self.field == "T": + return quantity_title + " (K)" + else: + return quantity_title + " (H m-3)" + else: + return quantity_title def compute(self, volume_markers): """Minimum of f over subdomains cells marked with self.volume""" diff --git a/festim/exports/derived_quantities/point_value.py b/festim/exports/derived_quantities/point_value.py index 10b046560..d038c2a2c 100644 --- a/festim/exports/derived_quantities/point_value.py +++ b/festim/exports/derived_quantities/point_value.py @@ -2,20 +2,43 @@ class PointValue(DerivedQuantity): - """DerivedQuantity relative to a point + """ + Computes the value of a field at a given point Args: - field (str, int): the field ("solute", 0, 1, "T", "retention") - point (int, float, tuple, list): the point coordinates + field (str, int): the field ("solute", 0, 1, "T", "retention") + x (int, float, tuple, list): the point coordinates + + Attributes: + field (str, int): the field ("solute", 0, 1, "T", "retention") + x (int, float, tuple, list): the point coordinates + show_units (bool): show the units in the title in the derived quantities + file + function (dolfin.function.function.Function): the solution function of + the field + + Notes: + Units are in H/m3 for hydrogen concentration and K for temperature + """ def __init__(self, field: str or int, x: int or float or tuple or list) -> None: - super().__init__(field) + super().__init__(field=field) # make sure x is an iterable if not hasattr(x, "__iter__"): x = [x] self.x = x - self.title = "{} value at {}".format(field, x) + + @property + def title(self): + quantity_title = f"{self.field} value at {self.x}" + if self.show_units: + if self.field == "T": + return quantity_title + " (K)" + else: + return quantity_title + " (H m-3)" + else: + return quantity_title def compute(self): """The value at the point""" diff --git a/festim/exports/derived_quantities/surface_flux.py b/festim/exports/derived_quantities/surface_flux.py index 227da62e3..0d6e9b7ad 100644 --- a/festim/exports/derived_quantities/surface_flux.py +++ b/festim/exports/derived_quantities/surface_flux.py @@ -4,24 +4,59 @@ class SurfaceFlux(SurfaceQuantity): - def __init__(self, field, surface) -> None: - """ + """ + Computes the surface flux of a field at a given surface + + Args: + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + + Attribtutes + field (str, int): the field ("solute", 0, 1, "T", "retention") + surface (int): the surface id + show_units (bool): show the units in the title in the derived quantities + file + title (str): the title of the derived quantity + function (dolfin.function.function.Function): the solution function of + the hydrogen solute field + + Notes: Object to compute the flux J of a field u through a surface J = integral(-prop * grad(u) . n ds) where prop is the property of the field (D, thermal conductivity, etc) u is the field n is the normal vector of the surface ds is the surface measure. + units are in H/m2/s in 1D, H/m/s in 2D and H/s in 3D domains for hydrogen + concentration and W/m2 in 1D, W/m in 2D and W in 3D domains for temperature - Note: this will probably won't work correctly for axisymmetric meshes. - Use only with cartesian coordinates. + """ - Args: - field (str, int): the field ("solute", 0, 1, "T", "retention") - surface (int): the surface id - """ + def __init__(self, field, surface) -> None: super().__init__(field=field, surface=surface) - self.title = "Flux surface {}: {}".format(self.surface, self.field) + + @property + def title(self): + quantity_title = f"Flux surface {self.surface}: {self.field}" + if self.show_units: + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if self.field == "T": + if dim == 1: + return quantity_title + " (W m-2)" + if dim == 2: + return quantity_title + " (W m-1)" + if dim == 3: + return quantity_title + " (W)" + else: + if dim == 1: + return quantity_title + " (H m-2 s-1)" + if dim == 2: + return quantity_title + " (H m-1 s-1)" + if dim == 3: + return quantity_title + " (H s-1)" + else: + return quantity_title @property def prop(self): @@ -69,10 +104,21 @@ class SurfaceFluxCylindrical(SurfaceFlux): """ def __init__(self, field, surface, azimuth_range=(0, 2 * np.pi)) -> None: - super().__init__(field, surface) + super().__init__(field=field, surface=surface) self.r = None self.azimuth_range = azimuth_range + @property + def title(self): + quantity_title = f"Cylindrical flux surface {self.surface}: {self.field}" + if self.show_units: + if self.field == "T": + return quantity_title + " (W)" + else: + return quantity_title + " (H s-1)" + else: + return quantity_title + @property def azimuth_range(self): return self._azimuth_range @@ -134,11 +180,22 @@ class SurfaceFluxSpherical(SurfaceFlux): def __init__( self, field, surface, azimuth_range=(0, np.pi), polar_range=(-np.pi, np.pi) ) -> None: - super().__init__(field, surface) + super().__init__(field=field, surface=surface) self.r = None self.polar_range = polar_range self.azimuth_range = azimuth_range + @property + def title(self): + quantity_title = f"Spherical flux surface {self.surface}: {self.field}" + if self.show_units: + if self.field == "T": + return quantity_title + " (W)" + else: + return quantity_title + " (H s-1)" + else: + return quantity_title + @property def polar_range(self): return self._polar_range diff --git a/festim/exports/derived_quantities/thermal_flux.py b/festim/exports/derived_quantities/thermal_flux.py index 176df3799..69cfe7c17 100644 --- a/festim/exports/derived_quantities/thermal_flux.py +++ b/festim/exports/derived_quantities/thermal_flux.py @@ -2,5 +2,40 @@ class ThermalFlux(SurfaceFlux): + """ + Computes the surface flux of heat at a given surface + + Args: + surface (int): the surface id + + Attribtutes + surface (int): the surface id + field (str): the temperature field + show_units (bool): show the units in the title in the derived quantities + file + title (str): the title of the derived quantity + function (dolfin.function.function.Function): the solution function of + the temperature field + + Notes: + units are in W/m2 in 1D, W/m in 2D and W in 3D domains + + """ + def __init__(self, surface) -> None: super().__init__(field="T", surface=surface) + + @property + def title(self): + quantity_title = f"Flux surface {self.surface}: {self.field}" + if self.show_units: + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if dim == 1: + return quantity_title + " (W m-2)" + if dim == 2: + return quantity_title + " (W m-1)" + if dim == 3: + return quantity_title + " (W)" + else: + return quantity_title diff --git a/festim/exports/derived_quantities/total_surface.py b/festim/exports/derived_quantities/total_surface.py index 057d7f9af..48717a8cb 100644 --- a/festim/exports/derived_quantities/total_surface.py +++ b/festim/exports/derived_quantities/total_surface.py @@ -3,9 +3,53 @@ class TotalSurface(SurfaceQuantity): + """ + Computes the total value of a field on a given surface + + Args: + field (str, int): the field + surface (int): the surface id + + Attribtutes + field (str, int): the field + surface (int): the surface id + show_units (bool): show the units in the title in the derived quantities + file + title (str): the title of the derived quantity + function (dolfin.function.function.Function): the solution function of + the hydrogen solute field + + Notes: + units are in H/m2 in 1D, H/m in 2D and H in 3D domains for hydrogen + concentration and K in 1D, K m in 2D and K m2 in 3D domains for temperature + + """ + def __init__(self, field, surface) -> None: - super().__init__(field, surface=surface) - self.title = "Total {} surface {}".format(self.field, self.surface) + super().__init__(field=field, surface=surface) + + @property + def title(self): + quantity_title = f"Total {self.field} surface {self.surface}" + if self.show_units: + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if self.field == "T": + if dim == 1: + return quantity_title + " (K)" + elif dim == 2: + return quantity_title + " (K m)" + elif dim == 3: + return quantity_title + " (K m2)" + else: + if dim == 1: + return quantity_title + " (H m-2)" + elif dim == 2: + return quantity_title + " (H m-1)" + elif dim == 3: + return quantity_title + " (H)" + else: + return quantity_title def compute(self): return f.assemble(self.function * self.ds(self.surface)) diff --git a/festim/exports/derived_quantities/total_volume.py b/festim/exports/derived_quantities/total_volume.py index 497db138b..b91e0f003 100644 --- a/festim/exports/derived_quantities/total_volume.py +++ b/festim/exports/derived_quantities/total_volume.py @@ -3,9 +3,53 @@ class TotalVolume(VolumeQuantity): + """ + Computes the total value of a field in a given volume + + Args: + field (str, int): the field + volume (int): the volume id + + Attribtutes + field (str, int): the field + volume (int): the volume id + show_units (bool): show the units in the title in the derived quantities + file + title (str): the title of the derived quantity + function (dolfin.function.function.Function): the solution function of + the hydrogen solute field + + Notes: + units are in H/m2 in 1D, H/m in 2D and H in 3D domains for hydrogen + concentration and K m in 1D, K m2 in 2D and K m3 in 3D domains for temperature + + """ + def __init__(self, field, volume) -> None: - super().__init__(field, volume=volume) - self.title = "Total {} volume {}".format(self.field, self.volume) + super().__init__(field=field, volume=volume) + + @property + def title(self): + quantity_title = f"Total {self.field} volume {self.volume}" + if self.show_units: + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if self.field == "T": + if dim == 1: + return quantity_title + " (K m)" + elif dim == 2: + return quantity_title + " (K m2)" + elif dim == 3: + return quantity_title + " (K m3)" + else: + if dim == 1: + return quantity_title + " (H m-2)" + elif dim == 2: + return quantity_title + " (H m-1)" + elif dim == 3: + return quantity_title + " (H)" + else: + return quantity_title def compute(self): return f.assemble(self.function * self.dx(self.volume)) diff --git a/festim/exports/exports.py b/festim/exports/exports.py index a84e80d9e..b79cd2f2b 100644 --- a/festim/exports/exports.py +++ b/festim/exports/exports.py @@ -136,6 +136,6 @@ def initialise_derived_quantities(self, dx, ds, materials): """ for export in self: if isinstance(export, festim.DerivedQuantities): - export.data = [export.make_header()] + export.data = [] export.assign_measures_to_quantities(dx, ds) export.assign_properties_to_quantities(materials) diff --git a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py index 1a81e91c5..2928d2fdc 100644 --- a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py +++ b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py @@ -6,6 +6,10 @@ TotalVolume, MaximumVolume, MinimumVolume, + MinimumSurface, + MaximumSurface, + AverageSurface, + PointValue, Materials, ) import fenics as f @@ -23,7 +27,17 @@ class TestMakeHeader: tot_surf_2 = TotalSurface("trap1", 7) tot_vol_1 = TotalVolume("trap2", 5) min_vol_1 = MinimumVolume("retention", 2) + min_vol_2 = MinimumVolume("T", 2) max_vol_1 = MaximumVolume("T", 2) + max_vol_2 = MaximumVolume("trap2", 2) + min_surface_1 = MinimumSurface("solute", 1) + min_surface_2 = MinimumSurface("T", 2) + max_surface_1 = MaximumSurface("solute", 8) + max_surface_2 = MaximumSurface("T", 9) + avg_surface_1 = AverageSurface("solute", 4) + avg_surface_2 = AverageSurface("T", 6) + point_1 = PointValue(field="retention", x=2) + point_2 = PointValue(field="T", x=9) def test_simple(self): """ @@ -76,6 +90,46 @@ def test_all_quantities(self): ] assert header == expected_header + def test_with_units_simple(self): + """Test with quantities that don't require mesh dimension for unit""" + my_derv_quant = DerivedQuantities( + [ + self.average_vol_1, + self.average_vol_2, + self.min_vol_1, + self.min_vol_2, + self.max_vol_1, + self.max_vol_2, + self.min_surface_1, + self.min_surface_2, + self.max_surface_1, + self.max_surface_2, + self.avg_surface_1, + self.avg_surface_2, + self.point_1, + self.point_2, + ], + show_units=True, + ) + header = my_derv_quant.make_header() + expected_header = ["t(s)"] + [ + "Average solute volume 3 (H m-3)", + "Average T volume 4 (K)", + "Minimum retention volume 2 (H m-3)", + "Minimum T volume 2 (K)", + "Maximum T volume 2 (K)", + "Maximum trap2 volume 2 (H m-3)", + "Minimum solute surface 1 (H m-3)", + "Minimum T surface 2 (K)", + "Maximum solute surface 8 (H m-3)", + "Maximum T surface 9 (K)", + "Average solute surface 4 (H m-3)", + "Average T surface 6 (K)", + "retention value at [2] (H m-3)", + "T value at [9] (K)", + ] + assert header == expected_header + class TestAssignMeasuresToQuantities: """ @@ -211,7 +265,7 @@ def test_simple(self): my_derv_quant.data = [] my_derv_quant.compute(t) - assert my_derv_quant.data[0] == expected_data + assert my_derv_quant.data[1] == expected_data def test_two_quantities(self): """Check for the case of two festim.DerivedQuantity objects""" @@ -232,7 +286,7 @@ def test_two_quantities(self): my_derv_quant.data = [] my_derv_quant.compute(t) - assert my_derv_quant.data[0] == expected_data + assert my_derv_quant.data[1] == expected_data def test_all_quantities(self): """Check for the case of many festim.DerivedQuantity objects""" @@ -262,7 +316,7 @@ def test_all_quantities(self): my_derv_quant.data = [] my_derv_quant.compute(t) - assert my_derv_quant.data[0] == expected_data + assert my_derv_quant.data[1] == expected_data class TestWrite: diff --git a/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py b/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py index 1b1b71181..bfc9e1b34 100644 --- a/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py @@ -1,4 +1,6 @@ from festim import HydrogenFlux +from .tools import c_1D, c_2D, c_3D +import pytest def test_field_is_solute(): @@ -9,3 +11,24 @@ def test_field_is_solute(): my_flux = HydrogenFlux(2) assert my_flux.field == "solute" + + +@pytest.mark.parametrize( + "function, expected_title", + [ + (c_1D, "Flux surface 3: solute (H m-2 s-1)"), + (c_2D, "Flux surface 3: solute (H m-1 s-1)"), + (c_3D, "Flux surface 3: solute (H s-1)"), + ], +) +def test_title_with_units(function, expected_title): + my_flux = HydrogenFlux(3) + my_flux.function = function + my_flux.show_units = True + + assert my_flux.title == expected_title + + +def test_title_without_units(): + my_flux = HydrogenFlux(4) + assert my_flux.title == "Flux surface 4: solute" diff --git a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py index 55446254e..16b142e55 100644 --- a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py @@ -3,6 +3,8 @@ import math import numpy as np import pytest +from festim import SurfaceFlux, k_B +from .tools import c_1D, c_2D, c_3D @pytest.mark.parametrize("field,surface", [("solute", 1), ("T", 2)]) @@ -264,3 +266,22 @@ def test_soret_raises_error_spherical(): my_flux = SurfaceFluxSpherical("T", 1) with pytest.raises(NotImplementedError): my_flux.compute(soret=True) + + +@pytest.mark.parametrize( + "function, field, expected_title", + [ + (c_1D, "solute", "Flux surface 3: solute (H m-2 s-1)"), + (c_1D, "T", "Flux surface 3: T (W m-2)"), + (c_2D, "solute", "Flux surface 3: solute (H m-1 s-1)"), + (c_2D, "T", "Flux surface 3: T (W m-1)"), + (c_3D, "solute", "Flux surface 3: solute (H s-1)"), + (c_3D, "T", "Flux surface 3: T (W)"), + ], +) +def test_title_with_units(function, field, expected_title): + my_flux = SurfaceFlux(field=field, surface=3) + my_flux.function = function + my_flux.show_units = True + + assert my_flux.title == expected_title diff --git a/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py b/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py index fac0e5f46..4c78881bc 100644 --- a/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py @@ -1,4 +1,6 @@ from festim import ThermalFlux +import pytest +from .tools import c_1D, c_2D, c_3D def test_field_is_T(): @@ -8,3 +10,25 @@ def test_field_is_T(): """ my_flux = ThermalFlux(2) assert my_flux.field == "T" + + +@pytest.mark.parametrize( + "function, expected_title", + [ + (c_1D, "Flux surface 5: T (W m-2)"), + (c_2D, "Flux surface 5: T (W m-1)"), + (c_3D, "Flux surface 5: T (W)"), + ], +) +def test_title_with_units(function, expected_title): + my_flux = ThermalFlux(5) + my_flux.function = function + my_flux.show_units = True + + assert my_flux.title == expected_title + + +def test_title_without_units(): + my_flux = ThermalFlux(5) + + assert my_flux.title == "Flux surface 5: T" diff --git a/test/unit/test_exports/test_derived_quantities/test_total_surface.py b/test/unit/test_exports/test_derived_quantities/test_total_surface.py index f5e152595..ea0cd8354 100644 --- a/test/unit/test_exports/test_derived_quantities/test_total_surface.py +++ b/test/unit/test_exports/test_derived_quantities/test_total_surface.py @@ -2,6 +2,8 @@ from festim import TotalSurface import fenics as f import pytest +from .tools import c_1D, c_2D, c_3D +import pytest @pytest.mark.parametrize("field,surface", [("solute", 1), ("T", 2)]) @@ -43,3 +45,22 @@ def test_minimum(self): produced = self.my_total.compute() assert produced == expected + + +@pytest.mark.parametrize( + "function, field, expected_title", + [ + (c_1D, "solute", "Total solute surface 8 (H m-2)"), + (c_1D, "T", "Total T surface 8 (K)"), + (c_2D, "solute", "Total solute surface 8 (H m-1)"), + (c_2D, "T", "Total T surface 8 (K m)"), + (c_3D, "solute", "Total solute surface 8 (H)"), + (c_3D, "T", "Total T surface 8 (K m2)"), + ], +) +def test_title_with_units(function, field, expected_title): + my_export = TotalSurface(surface=8, field=field) + my_export.function = function + my_export.show_units = True + + assert my_export.title == expected_title diff --git a/test/unit/test_exports/test_derived_quantities/test_total_volume.py b/test/unit/test_exports/test_derived_quantities/test_total_volume.py index 8f2e3cfa5..5fd3a8cb3 100644 --- a/test/unit/test_exports/test_derived_quantities/test_total_volume.py +++ b/test/unit/test_exports/test_derived_quantities/test_total_volume.py @@ -1,6 +1,8 @@ from festim import TotalVolume import fenics as f import pytest +from .tools import c_1D, c_2D, c_3D +import pytest @pytest.mark.parametrize("field,volume", [("solute", 1), ("T", 2)]) @@ -42,3 +44,22 @@ def test_minimum(self): produced = self.my_total.compute() assert produced == expected + + +@pytest.mark.parametrize( + "function, field, expected_title", + [ + (c_1D, "solute", "Total solute volume 2 (H m-2)"), + (c_1D, "T", "Total T volume 2 (K m)"), + (c_2D, "solute", "Total solute volume 2 (H m-1)"), + (c_2D, "T", "Total T volume 2 (K m2)"), + (c_3D, "solute", "Total solute volume 2 (H)"), + (c_3D, "T", "Total T volume 2 (K m3)"), + ], +) +def test_title_with_units(function, field, expected_title): + my_export = TotalVolume(volume=2, field=field) + my_export.function = function + my_export.show_units = True + + assert my_export.title == expected_title diff --git a/test/unit/test_exports/test_derived_quantities/tools.py b/test/unit/test_exports/test_derived_quantities/tools.py new file mode 100644 index 000000000..8f9ce3089 --- /dev/null +++ b/test/unit/test_exports/test_derived_quantities/tools.py @@ -0,0 +1,13 @@ +import fenics as f + +mesh_1D = f.UnitIntervalMesh(10) +V_1D = f.FunctionSpace(mesh_1D, "P", 1) +c_1D = f.interpolate(f.Expression("x[0]", degree=1), V_1D) + +mesh_2D = f.UnitSquareMesh(10, 10) +V_2D = f.FunctionSpace(mesh_2D, "P", 1) +c_2D = f.interpolate(f.Expression("x[0]", degree=1), V_2D) + +mesh_3D = f.UnitCubeMesh(10, 10, 10) +V_3D = f.FunctionSpace(mesh_3D, "P", 1) +c_3D = f.interpolate(f.Expression("x[0]", degree=1), V_3D) From 2518e09c42ae2be3bf38da16b3adad47b2902356 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 17:08:11 +0200 Subject: [PATCH 02/20] changes for comments from reveiw --- .../exports/derived_quantities/average_surface.py | 6 +++++- .../exports/derived_quantities/average_volume.py | 4 ++++ .../exports/derived_quantities/hydrogen_flux.py | 15 --------------- festim/exports/derived_quantities/surface_flux.py | 4 ++-- festim/exports/derived_quantities/thermal_flux.py | 15 --------------- .../exports/derived_quantities/total_surface.py | 1 + festim/exports/derived_quantities/total_volume.py | 1 + 7 files changed, 13 insertions(+), 33 deletions(-) diff --git a/festim/exports/derived_quantities/average_surface.py b/festim/exports/derived_quantities/average_surface.py index cc0dd42dd..18ed890c0 100644 --- a/festim/exports/derived_quantities/average_surface.py +++ b/festim/exports/derived_quantities/average_surface.py @@ -5,10 +5,12 @@ class AverageSurface(SurfaceQuantity): """ Computes the average value of a field on a given surface - int( f dx) / int (1 * dx) + int( f ds) / int (1 * ds) + Args: field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id @@ -16,8 +18,10 @@ class AverageSurface(SurfaceQuantity): file function (dolfin.function.function.Function): the solution function of the field + Notes: Units are in H/m3 for hydrogen concentration and K for temperature + """ def __init__(self, field, surface) -> None: diff --git a/festim/exports/derived_quantities/average_volume.py b/festim/exports/derived_quantities/average_volume.py index 2d7fb87e0..f385631c4 100644 --- a/festim/exports/derived_quantities/average_volume.py +++ b/festim/exports/derived_quantities/average_volume.py @@ -5,9 +5,12 @@ class AverageVolume(VolumeQuantity): """ Computes the average value of a field in a given volume + int( f ds) / int (1 * ds) + Args: field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id + Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id @@ -15,6 +18,7 @@ class AverageVolume(VolumeQuantity): file function (dolfin.function.function.Function): the solution function of the field + Notes: Units are in H/m3 for hydrogen concentration and K for temperature """ diff --git a/festim/exports/derived_quantities/hydrogen_flux.py b/festim/exports/derived_quantities/hydrogen_flux.py index e81370ab8..4226e6f1b 100644 --- a/festim/exports/derived_quantities/hydrogen_flux.py +++ b/festim/exports/derived_quantities/hydrogen_flux.py @@ -24,18 +24,3 @@ class HydrogenFlux(SurfaceFlux): def __init__(self, surface) -> None: super().__init__(field="solute", surface=surface) - - @property - def title(self): - quantity_title = f"Flux surface {self.surface}: {self.field}" - if self.show_units: - # obtain domain dimension - dim = self.function.function_space().mesh().topology().dim() - if dim == 1: - return quantity_title + " (H m-2 s-1)" - if dim == 2: - return quantity_title + " (H m-1 s-1)" - if dim == 3: - return quantity_title + " (H s-1)" - else: - return quantity_title diff --git a/festim/exports/derived_quantities/surface_flux.py b/festim/exports/derived_quantities/surface_flux.py index 0d6e9b7ad..f428979be 100644 --- a/festim/exports/derived_quantities/surface_flux.py +++ b/festim/exports/derived_quantities/surface_flux.py @@ -5,7 +5,7 @@ class SurfaceFlux(SurfaceQuantity): """ - Computes the surface flux of a field at a given surface + Computes the surface flux of a field at a given surface in cartesian coordinates Args: field (str, int): the field ("solute", 0, 1, "T", "retention") @@ -18,7 +18,7 @@ class SurfaceFlux(SurfaceQuantity): file title (str): the title of the derived quantity function (dolfin.function.function.Function): the solution function of - the hydrogen solute field + the field Notes: Object to compute the flux J of a field u through a surface diff --git a/festim/exports/derived_quantities/thermal_flux.py b/festim/exports/derived_quantities/thermal_flux.py index 69cfe7c17..3095908fe 100644 --- a/festim/exports/derived_quantities/thermal_flux.py +++ b/festim/exports/derived_quantities/thermal_flux.py @@ -24,18 +24,3 @@ class ThermalFlux(SurfaceFlux): def __init__(self, surface) -> None: super().__init__(field="T", surface=surface) - - @property - def title(self): - quantity_title = f"Flux surface {self.surface}: {self.field}" - if self.show_units: - # obtain domain dimension - dim = self.function.function_space().mesh().topology().dim() - if dim == 1: - return quantity_title + " (W m-2)" - if dim == 2: - return quantity_title + " (W m-1)" - if dim == 3: - return quantity_title + " (W)" - else: - return quantity_title diff --git a/festim/exports/derived_quantities/total_surface.py b/festim/exports/derived_quantities/total_surface.py index 48717a8cb..2cd821883 100644 --- a/festim/exports/derived_quantities/total_surface.py +++ b/festim/exports/derived_quantities/total_surface.py @@ -5,6 +5,7 @@ class TotalSurface(SurfaceQuantity): """ Computes the total value of a field on a given surface + int(f ds) Args: field (str, int): the field diff --git a/festim/exports/derived_quantities/total_volume.py b/festim/exports/derived_quantities/total_volume.py index b91e0f003..89d21bda0 100644 --- a/festim/exports/derived_quantities/total_volume.py +++ b/festim/exports/derived_quantities/total_volume.py @@ -5,6 +5,7 @@ class TotalVolume(VolumeQuantity): """ Computes the total value of a field in a given volume + int(f dx) Args: field (str, int): the field From fdf066852c4afd323fe2a96d43460399d2744758 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 17:08:17 +0200 Subject: [PATCH 03/20] increase coverage --- .../test_derived_quantities.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py index 2928d2fdc..3cdde3821 100644 --- a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py +++ b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py @@ -10,6 +10,8 @@ MaximumSurface, AverageSurface, PointValue, + SurfaceFluxCylindrical, + SurfaceFluxSpherical, Materials, ) import fenics as f @@ -38,6 +40,10 @@ class TestMakeHeader: avg_surface_2 = AverageSurface("T", 6) point_1 = PointValue(field="retention", x=2) point_2 = PointValue(field="T", x=9) + cyl_surface_flux_1 = SurfaceFluxCylindrical("solute", 2) + cyl_surface_flux_2 = SurfaceFluxCylindrical("T", 3) + sph_surface_flux_1 = SurfaceFluxSpherical("solute", 5) + sph_surface_flux_2 = SurfaceFluxSpherical("T", 6) def test_simple(self): """ @@ -108,6 +114,10 @@ def test_with_units_simple(self): self.avg_surface_2, self.point_1, self.point_2, + self.cyl_surface_flux_1, + self.cyl_surface_flux_2, + self.sph_surface_flux_1, + self.sph_surface_flux_2, ], show_units=True, ) @@ -127,6 +137,10 @@ def test_with_units_simple(self): "Average T surface 6 (K)", "retention value at [2] (H m-3)", "T value at [9] (K)", + "Cylindrical flux surface 2: solute (H s-1)", + "Cylindrical flux surface 3: T (W)", + "Spherical flux surface 5: solute (H s-1)", + "Spherical flux surface 6: T (W)", ] assert header == expected_header From 070cb1d92dd10a0e464f2d903e7189f6423a3b59 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 17:16:29 +0200 Subject: [PATCH 04/20] remove whitespace --- festim/exports/derived_quantities/average_surface.py | 2 +- festim/exports/derived_quantities/average_volume.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/festim/exports/derived_quantities/average_surface.py b/festim/exports/derived_quantities/average_surface.py index 18ed890c0..8ae471231 100644 --- a/festim/exports/derived_quantities/average_surface.py +++ b/festim/exports/derived_quantities/average_surface.py @@ -5,7 +5,7 @@ class AverageSurface(SurfaceQuantity): """ Computes the average value of a field on a given surface - int( f ds) / int (1 * ds) + int(f ds) / int (1 * ds) Args: field (str, int): the field ("solute", 0, 1, "T", "retention") diff --git a/festim/exports/derived_quantities/average_volume.py b/festim/exports/derived_quantities/average_volume.py index f385631c4..5add33232 100644 --- a/festim/exports/derived_quantities/average_volume.py +++ b/festim/exports/derived_quantities/average_volume.py @@ -5,7 +5,7 @@ class AverageVolume(VolumeQuantity): """ Computes the average value of a field in a given volume - int( f ds) / int (1 * ds) + int(f ds) / int (1 * ds) Args: field (str, int): the field ("solute", 0, 1, "T", "retention") From 8c02f7191607e6fed20d80e719f92a7b7e4a0bdd Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 17:20:47 +0200 Subject: [PATCH 05/20] can only be str --- festim/exports/derived_quantities/hydrogen_flux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/festim/exports/derived_quantities/hydrogen_flux.py b/festim/exports/derived_quantities/hydrogen_flux.py index 4226e6f1b..24a668a46 100644 --- a/festim/exports/derived_quantities/hydrogen_flux.py +++ b/festim/exports/derived_quantities/hydrogen_flux.py @@ -9,7 +9,7 @@ class HydrogenFlux(SurfaceFlux): surface (int): the surface id Attribtutes - field (str, int): the hydrogen solute field + field (str): the hydrogen solute field surface (int): the surface id show_units (bool): show the units in the title in the derived quantities file From 4b8248b29adafb25a03a996a7368a840e7a2ba77 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 17:21:08 +0200 Subject: [PATCH 06/20] better consistency in doc strings --- festim/exports/derived_quantities/total_surface.py | 4 ++-- festim/exports/derived_quantities/total_volume.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/festim/exports/derived_quantities/total_surface.py b/festim/exports/derived_quantities/total_surface.py index 2cd821883..44f5b3d8d 100644 --- a/festim/exports/derived_quantities/total_surface.py +++ b/festim/exports/derived_quantities/total_surface.py @@ -8,11 +8,11 @@ class TotalSurface(SurfaceQuantity): int(f ds) Args: - field (str, int): the field + field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id Attribtutes - field (str, int): the field + field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id show_units (bool): show the units in the title in the derived quantities file diff --git a/festim/exports/derived_quantities/total_volume.py b/festim/exports/derived_quantities/total_volume.py index 89d21bda0..96f236e53 100644 --- a/festim/exports/derived_quantities/total_volume.py +++ b/festim/exports/derived_quantities/total_volume.py @@ -8,11 +8,11 @@ class TotalVolume(VolumeQuantity): int(f dx) Args: - field (str, int): the field + field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id Attribtutes - field (str, int): the field + field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id show_units (bool): show the units in the title in the derived quantities file From d49cf9e2319a9376c83caea791bc04a5228e9f1d Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 17:24:42 +0200 Subject: [PATCH 07/20] added clarification inline comment --- .../test_derived_quantities/test_derived_quantities.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py index 3cdde3821..652c96f5a 100644 --- a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py +++ b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py @@ -279,6 +279,10 @@ def test_simple(self): my_derv_quant.data = [] my_derv_quant.compute(t) + + # title created in compute() method and appended to data + # so test line 2 for first data entry + assert my_derv_quant.data[1] == expected_data def test_two_quantities(self): @@ -300,6 +304,9 @@ def test_two_quantities(self): my_derv_quant.data = [] my_derv_quant.compute(t) + # title created in compute() method and appended to data + # so test line 2 for first data entry + assert my_derv_quant.data[1] == expected_data def test_all_quantities(self): @@ -330,6 +337,9 @@ def test_all_quantities(self): my_derv_quant.data = [] my_derv_quant.compute(t) + # title created in compute() method and appended to data + # so test line 2 for first data entry + assert my_derv_quant.data[1] == expected_data From 1282110583f81fb067e2c00f8454ca42f8feabeb Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 17:29:14 +0200 Subject: [PATCH 08/20] title is an attribute --- festim/exports/derived_quantities/average_surface.py | 1 + festim/exports/derived_quantities/average_volume.py | 1 + festim/exports/derived_quantities/hydrogen_flux.py | 2 +- festim/exports/derived_quantities/maximum_surface.py | 1 + festim/exports/derived_quantities/maximum_volume.py | 1 + festim/exports/derived_quantities/minimum_surface.py | 1 + festim/exports/derived_quantities/minimum_volume.py | 1 + festim/exports/derived_quantities/point_value.py | 1 + festim/exports/derived_quantities/surface_flux.py | 2 +- festim/exports/derived_quantities/thermal_flux.py | 2 +- festim/exports/derived_quantities/total_surface.py | 2 +- festim/exports/derived_quantities/total_volume.py | 2 +- 12 files changed, 12 insertions(+), 5 deletions(-) diff --git a/festim/exports/derived_quantities/average_surface.py b/festim/exports/derived_quantities/average_surface.py index 8ae471231..a6d994c02 100644 --- a/festim/exports/derived_quantities/average_surface.py +++ b/festim/exports/derived_quantities/average_surface.py @@ -14,6 +14,7 @@ class AverageSurface(SurfaceQuantity): Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file function (dolfin.function.function.Function): the solution function of diff --git a/festim/exports/derived_quantities/average_volume.py b/festim/exports/derived_quantities/average_volume.py index 5add33232..651751f70 100644 --- a/festim/exports/derived_quantities/average_volume.py +++ b/festim/exports/derived_quantities/average_volume.py @@ -14,6 +14,7 @@ class AverageVolume(VolumeQuantity): Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file function (dolfin.function.function.Function): the solution function of diff --git a/festim/exports/derived_quantities/hydrogen_flux.py b/festim/exports/derived_quantities/hydrogen_flux.py index 24a668a46..26f39626c 100644 --- a/festim/exports/derived_quantities/hydrogen_flux.py +++ b/festim/exports/derived_quantities/hydrogen_flux.py @@ -11,9 +11,9 @@ class HydrogenFlux(SurfaceFlux): Attribtutes field (str): the hydrogen solute field surface (int): the surface id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file - title (str): the title of the derived quantity function (dolfin.function.function.Function): the solution function of the hydrogen solute field diff --git a/festim/exports/derived_quantities/maximum_surface.py b/festim/exports/derived_quantities/maximum_surface.py index 54726c87e..f4b790755 100644 --- a/festim/exports/derived_quantities/maximum_surface.py +++ b/festim/exports/derived_quantities/maximum_surface.py @@ -14,6 +14,7 @@ class MaximumSurface(SurfaceQuantity): Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file function (dolfin.function.function.Function): the solution function of diff --git a/festim/exports/derived_quantities/maximum_volume.py b/festim/exports/derived_quantities/maximum_volume.py index 315c5a79a..62eee2100 100644 --- a/festim/exports/derived_quantities/maximum_volume.py +++ b/festim/exports/derived_quantities/maximum_volume.py @@ -14,6 +14,7 @@ class MaximumVolume(VolumeQuantity): Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file function (dolfin.function.function.Function): the solution function for diff --git a/festim/exports/derived_quantities/minimum_surface.py b/festim/exports/derived_quantities/minimum_surface.py index 6da9f6b16..f782db5f0 100644 --- a/festim/exports/derived_quantities/minimum_surface.py +++ b/festim/exports/derived_quantities/minimum_surface.py @@ -14,6 +14,7 @@ class MinimumSurface(SurfaceQuantity): Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file function (dolfin.function.function.Function): the solution function of diff --git a/festim/exports/derived_quantities/minimum_volume.py b/festim/exports/derived_quantities/minimum_volume.py index 36cd4c01e..e3277c522 100644 --- a/festim/exports/derived_quantities/minimum_volume.py +++ b/festim/exports/derived_quantities/minimum_volume.py @@ -14,6 +14,7 @@ class MinimumVolume(VolumeQuantity): Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file function (dolfin.function.function.Function): the solution function for diff --git a/festim/exports/derived_quantities/point_value.py b/festim/exports/derived_quantities/point_value.py index d038c2a2c..80d5a82e0 100644 --- a/festim/exports/derived_quantities/point_value.py +++ b/festim/exports/derived_quantities/point_value.py @@ -12,6 +12,7 @@ class PointValue(DerivedQuantity): Attributes: field (str, int): the field ("solute", 0, 1, "T", "retention") x (int, float, tuple, list): the point coordinates + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file function (dolfin.function.function.Function): the solution function of diff --git a/festim/exports/derived_quantities/surface_flux.py b/festim/exports/derived_quantities/surface_flux.py index f428979be..1e106a033 100644 --- a/festim/exports/derived_quantities/surface_flux.py +++ b/festim/exports/derived_quantities/surface_flux.py @@ -14,9 +14,9 @@ class SurfaceFlux(SurfaceQuantity): Attribtutes field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file - title (str): the title of the derived quantity function (dolfin.function.function.Function): the solution function of the field diff --git a/festim/exports/derived_quantities/thermal_flux.py b/festim/exports/derived_quantities/thermal_flux.py index 3095908fe..8dd4b4032 100644 --- a/festim/exports/derived_quantities/thermal_flux.py +++ b/festim/exports/derived_quantities/thermal_flux.py @@ -11,9 +11,9 @@ class ThermalFlux(SurfaceFlux): Attribtutes surface (int): the surface id field (str): the temperature field + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file - title (str): the title of the derived quantity function (dolfin.function.function.Function): the solution function of the temperature field diff --git a/festim/exports/derived_quantities/total_surface.py b/festim/exports/derived_quantities/total_surface.py index 44f5b3d8d..2fe7d8c0e 100644 --- a/festim/exports/derived_quantities/total_surface.py +++ b/festim/exports/derived_quantities/total_surface.py @@ -14,9 +14,9 @@ class TotalSurface(SurfaceQuantity): Attribtutes field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file - title (str): the title of the derived quantity function (dolfin.function.function.Function): the solution function of the hydrogen solute field diff --git a/festim/exports/derived_quantities/total_volume.py b/festim/exports/derived_quantities/total_volume.py index 96f236e53..f61675cec 100644 --- a/festim/exports/derived_quantities/total_volume.py +++ b/festim/exports/derived_quantities/total_volume.py @@ -14,9 +14,9 @@ class TotalVolume(VolumeQuantity): Attribtutes field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id + title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file - title (str): the title of the derived quantity function (dolfin.function.function.Function): the solution function of the hydrogen solute field From c833b4b0402d5a79a27599cc0f02f8b217717575 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 18:05:31 +0200 Subject: [PATCH 09/20] new title naming scheme for fluxes --- .../derived_quantities/surface_flux.py | 15 ++++++++-- .../test_derived_quantities.py | 8 +++--- .../test_hydrogen_flux.py | 6 ++-- .../test_surface_flux.py | 28 +++++++++++++++---- .../test_thermal_flux.py | 6 ++-- 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/festim/exports/derived_quantities/surface_flux.py b/festim/exports/derived_quantities/surface_flux.py index 1e106a033..81b82cfc3 100644 --- a/festim/exports/derived_quantities/surface_flux.py +++ b/festim/exports/derived_quantities/surface_flux.py @@ -41,7 +41,10 @@ def title(self): if self.show_units: # obtain domain dimension dim = self.function.function_space().mesh().topology().dim() + # new title but only with show_units to not introduce breaking change + quantity_title = f"{self.field} flux surface {self.surface}" if self.field == "T": + quantity_title = f"Heat flux surface {self.surface}" if dim == 1: return quantity_title + " (W m-2)" if dim == 2: @@ -110,7 +113,11 @@ def __init__(self, field, surface, azimuth_range=(0, 2 * np.pi)) -> None: @property def title(self): - quantity_title = f"Cylindrical flux surface {self.surface}: {self.field}" + if self.field == "T": + quantity_title = f"Heat flux surface {self.surface}" + else: + quantity_title = f"{self.field} flux surface {self.surface}" + if self.show_units: if self.field == "T": return quantity_title + " (W)" @@ -187,7 +194,11 @@ def __init__( @property def title(self): - quantity_title = f"Spherical flux surface {self.surface}: {self.field}" + if self.field == "T": + quantity_title = f"Heat flux surface {self.surface}" + else: + quantity_title = f"{self.field} flux surface {self.surface}" + if self.show_units: if self.field == "T": return quantity_title + " (W)" diff --git a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py index 652c96f5a..b6b198df4 100644 --- a/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py +++ b/test/unit/test_exports/test_derived_quantities/test_derived_quantities.py @@ -137,10 +137,10 @@ def test_with_units_simple(self): "Average T surface 6 (K)", "retention value at [2] (H m-3)", "T value at [9] (K)", - "Cylindrical flux surface 2: solute (H s-1)", - "Cylindrical flux surface 3: T (W)", - "Spherical flux surface 5: solute (H s-1)", - "Spherical flux surface 6: T (W)", + "solute flux surface 2 (H s-1)", + "Heat flux surface 3 (W)", + "solute flux surface 5 (H s-1)", + "Heat flux surface 6 (W)", ] assert header == expected_header diff --git a/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py b/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py index bfc9e1b34..96aa175e4 100644 --- a/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_hydrogen_flux.py @@ -16,9 +16,9 @@ def test_field_is_solute(): @pytest.mark.parametrize( "function, expected_title", [ - (c_1D, "Flux surface 3: solute (H m-2 s-1)"), - (c_2D, "Flux surface 3: solute (H m-1 s-1)"), - (c_3D, "Flux surface 3: solute (H s-1)"), + (c_1D, "solute flux surface 3 (H m-2 s-1)"), + (c_2D, "solute flux surface 3 (H m-1 s-1)"), + (c_3D, "solute flux surface 3 (H s-1)"), ], ) def test_title_with_units(function, expected_title): diff --git a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py index 16b142e55..8b7df3908 100644 --- a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py @@ -271,12 +271,12 @@ def test_soret_raises_error_spherical(): @pytest.mark.parametrize( "function, field, expected_title", [ - (c_1D, "solute", "Flux surface 3: solute (H m-2 s-1)"), - (c_1D, "T", "Flux surface 3: T (W m-2)"), - (c_2D, "solute", "Flux surface 3: solute (H m-1 s-1)"), - (c_2D, "T", "Flux surface 3: T (W m-1)"), - (c_3D, "solute", "Flux surface 3: solute (H s-1)"), - (c_3D, "T", "Flux surface 3: T (W)"), + (c_1D, "solute", "solute flux surface 3 (H m-2 s-1)"), + (c_1D, "T", "Heat flux surface 3 (W m-2)"), + (c_2D, "solute", "solute flux surface 3 (H m-1 s-1)"), + (c_2D, "T", "Heat flux surface 3 (W m-1)"), + (c_3D, "solute", "solute flux surface 3 (H s-1)"), + (c_3D, "T", "Heat flux surface 3 (W)"), ], ) def test_title_with_units(function, field, expected_title): @@ -285,3 +285,19 @@ def test_title_with_units(function, field, expected_title): my_flux.show_units = True assert my_flux.title == expected_title + + +def test_cyldrical_flux_title_no_units_solute(): + """A simple test to check that the title is set correctly in + festim.CylindricalSurfaceFlux with a solute field without units""" + + my_h_flux = SurfaceFluxCylindrical("solute", 2) + assert my_h_flux.title == "solute flux surface 2" + + +def test_cyldrical_flux_title_no_units_temperature(): + """A simple test to check that the title is set correctly in + festim.CylindricalSurfaceFlux with a solute field without units""" + + my_heat_flux = SurfaceFluxCylindrical("T", 4) + assert my_heat_flux.title == "Heat flux surface 4" diff --git a/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py b/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py index 4c78881bc..92776a1b9 100644 --- a/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_thermal_flux.py @@ -15,9 +15,9 @@ def test_field_is_T(): @pytest.mark.parametrize( "function, expected_title", [ - (c_1D, "Flux surface 5: T (W m-2)"), - (c_2D, "Flux surface 5: T (W m-1)"), - (c_3D, "Flux surface 5: T (W)"), + (c_1D, "Heat flux surface 5 (W m-2)"), + (c_2D, "Heat flux surface 5 (W m-1)"), + (c_3D, "Heat flux surface 5 (W)"), ], ) def test_title_with_units(function, expected_title): From 05d7a2078e0fdbe60cf9296492c536545e7fd33a Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 18:07:41 +0200 Subject: [PATCH 10/20] typo and better coverage --- .../test_surface_flux.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py index 8b7df3908..47dff6a72 100644 --- a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py @@ -287,7 +287,7 @@ def test_title_with_units(function, field, expected_title): assert my_flux.title == expected_title -def test_cyldrical_flux_title_no_units_solute(): +def test_cylindrical_flux_title_no_units_solute(): """A simple test to check that the title is set correctly in festim.CylindricalSurfaceFlux with a solute field without units""" @@ -295,9 +295,25 @@ def test_cyldrical_flux_title_no_units_solute(): assert my_h_flux.title == "solute flux surface 2" -def test_cyldrical_flux_title_no_units_temperature(): +def test_cylindrical_flux_title_no_units_temperature(): """A simple test to check that the title is set correctly in - festim.CylindricalSurfaceFlux with a solute field without units""" + festim.CylindricalSurfaceFlux with a T field without units""" my_heat_flux = SurfaceFluxCylindrical("T", 4) assert my_heat_flux.title == "Heat flux surface 4" + + +def test_spherical_flux_title_no_units_solute(): + """A simple test to check that the title is set correctly in + festim.SphericalSurfaceFlux with a solute field without units""" + + my_h_flux = SurfaceFluxCylindrical("solute", 3) + assert my_h_flux.title == "solute flux surface 3" + + +def test_spherical_flux_title_no_units_temperature(): + """A simple test to check that the title is set correctly in + festim.CSphericalSurfaceFlux with a T field without units""" + + my_heat_flux = SurfaceFluxCylindrical("T", 5) + assert my_heat_flux.title == "Heat flux surface 5" From 1f728b142a946eddca473e0b7cf17c38acff9ff3 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 18:18:35 +0200 Subject: [PATCH 11/20] typo --- .../test_exports/test_derived_quantities/test_surface_flux.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py index 47dff6a72..b6d3323be 100644 --- a/test/unit/test_exports/test_derived_quantities/test_surface_flux.py +++ b/test/unit/test_exports/test_derived_quantities/test_surface_flux.py @@ -307,7 +307,7 @@ def test_spherical_flux_title_no_units_solute(): """A simple test to check that the title is set correctly in festim.SphericalSurfaceFlux with a solute field without units""" - my_h_flux = SurfaceFluxCylindrical("solute", 3) + my_h_flux = SurfaceFluxSpherical("solute", 3) assert my_h_flux.title == "solute flux surface 3" @@ -315,5 +315,5 @@ def test_spherical_flux_title_no_units_temperature(): """A simple test to check that the title is set correctly in festim.CSphericalSurfaceFlux with a T field without units""" - my_heat_flux = SurfaceFluxCylindrical("T", 5) + my_heat_flux = SurfaceFluxSpherical("T", 5) assert my_heat_flux.title == "Heat flux surface 5" From 8f5e09b7d88f944c1f7425f10fa687f82695dcdd Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 20:15:44 +0200 Subject: [PATCH 12/20] fixed doc string, unit property --- .../derived_quantities/surface_flux.py | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/festim/exports/derived_quantities/surface_flux.py b/festim/exports/derived_quantities/surface_flux.py index 81b82cfc3..33a6517d4 100644 --- a/festim/exports/derived_quantities/surface_flux.py +++ b/festim/exports/derived_quantities/surface_flux.py @@ -14,6 +14,7 @@ class SurfaceFlux(SurfaceQuantity): Attribtutes field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + export_unit (str): the unit of the derived quantity in the export file title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file @@ -22,7 +23,7 @@ class SurfaceFlux(SurfaceQuantity): Notes: Object to compute the flux J of a field u through a surface - J = integral(-prop * grad(u) . n ds) + J = integral(+prop * grad(u) . n ds) where prop is the property of the field (D, thermal conductivity, etc) u is the field n is the normal vector of the surface @@ -35,29 +36,36 @@ class SurfaceFlux(SurfaceQuantity): def __init__(self, field, surface) -> None: super().__init__(field=field, surface=surface) + @property + def export_unit(self): + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if self.field == "T": + if dim == 1: + return "W m-2" + if dim == 2: + return "W m-1" + if dim == 3: + return "W" + else: + if dim == 1: + return "H m-2 s-1" + if dim == 2: + return "H m-1 s-1" + if dim == 3: + return "H s-1" + @property def title(self): quantity_title = f"Flux surface {self.surface}: {self.field}" if self.show_units: - # obtain domain dimension - dim = self.function.function_space().mesh().topology().dim() - # new title but only with show_units to not introduce breaking change - quantity_title = f"{self.field} flux surface {self.surface}" if self.field == "T": quantity_title = f"Heat flux surface {self.surface}" - if dim == 1: - return quantity_title + " (W m-2)" - if dim == 2: - return quantity_title + " (W m-1)" - if dim == 3: - return quantity_title + " (W)" else: - if dim == 1: - return quantity_title + " (H m-2 s-1)" - if dim == 2: - return quantity_title + " (H m-1 s-1)" - if dim == 3: - return quantity_title + " (H s-1)" + quantity_title = f"{self.field} flux surface {self.surface}" + + return quantity_title + f" ({self.export_unit})" + else: return quantity_title From 73a963b1856fb0ceb3dfc6b7bea05b7c9118ed66 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 20:16:27 +0200 Subject: [PATCH 13/20] warning if show_units False --- festim/exports/derived_quantities/derived_quantities.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/festim/exports/derived_quantities/derived_quantities.py b/festim/exports/derived_quantities/derived_quantities.py index 3cef88ad9..2d5defe70 100644 --- a/festim/exports/derived_quantities/derived_quantities.py +++ b/festim/exports/derived_quantities/derived_quantities.py @@ -113,6 +113,11 @@ def make_header(self): header = ["t(s)"] for quantity in self: quantity.show_units = self.show_units + if self.show_units is False: + warnings.warn( + "The derived_quantities ti will be deprecated in a future release, please use festim.DerivedQuantities as a list instead", + DeprecationWarning, + ) header.append(quantity.title) return header From f930d5dd2ead273ffe71d21fc4640139ab5d83c9 Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 21:32:42 +0200 Subject: [PATCH 14/20] different warning --- festim/exports/derived_quantities/derived_quantities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/festim/exports/derived_quantities/derived_quantities.py b/festim/exports/derived_quantities/derived_quantities.py index 2d5defe70..4664f0ad5 100644 --- a/festim/exports/derived_quantities/derived_quantities.py +++ b/festim/exports/derived_quantities/derived_quantities.py @@ -115,7 +115,7 @@ def make_header(self): quantity.show_units = self.show_units if self.show_units is False: warnings.warn( - "The derived_quantities ti will be deprecated in a future release, please use festim.DerivedQuantities as a list instead", + "The current derived_quantities title style will be deprecated in a future release, please use show_units=True instead", DeprecationWarning, ) header.append(quantity.title) From 7eb4e31c9e41b301fbda8859da304fd4903e918f Mon Sep 17 00:00:00 2001 From: J Dark Date: Thu, 4 Apr 2024 21:33:34 +0200 Subject: [PATCH 15/20] total values with export unit property --- .../derived_quantities/total_surface.py | 37 +++++++++++-------- .../derived_quantities/total_volume.py | 37 +++++++++++-------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/festim/exports/derived_quantities/total_surface.py b/festim/exports/derived_quantities/total_surface.py index 2fe7d8c0e..04a3a6a25 100644 --- a/festim/exports/derived_quantities/total_surface.py +++ b/festim/exports/derived_quantities/total_surface.py @@ -14,6 +14,7 @@ class TotalSurface(SurfaceQuantity): Attribtutes field (str, int): the field ("solute", 0, 1, "T", "retention") surface (int): the surface id + export_unit (str): the unit of the derived quantity for exporting title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file @@ -29,26 +30,30 @@ class TotalSurface(SurfaceQuantity): def __init__(self, field, surface) -> None: super().__init__(field=field, surface=surface) + @property + def export_unit(self): + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if self.field == "T": + if dim == 1: + return "K" + if dim == 2: + return "K m" + if dim == 3: + return "K m2" + else: + if dim == 1: + return "H m-2" + if dim == 2: + return "H m-1" + if dim == 3: + return "H" + @property def title(self): quantity_title = f"Total {self.field} surface {self.surface}" if self.show_units: - # obtain domain dimension - dim = self.function.function_space().mesh().topology().dim() - if self.field == "T": - if dim == 1: - return quantity_title + " (K)" - elif dim == 2: - return quantity_title + " (K m)" - elif dim == 3: - return quantity_title + " (K m2)" - else: - if dim == 1: - return quantity_title + " (H m-2)" - elif dim == 2: - return quantity_title + " (H m-1)" - elif dim == 3: - return quantity_title + " (H)" + return quantity_title + f" ({self.export_unit})" else: return quantity_title diff --git a/festim/exports/derived_quantities/total_volume.py b/festim/exports/derived_quantities/total_volume.py index f61675cec..141e8cada 100644 --- a/festim/exports/derived_quantities/total_volume.py +++ b/festim/exports/derived_quantities/total_volume.py @@ -14,6 +14,7 @@ class TotalVolume(VolumeQuantity): Attribtutes field (str, int): the field ("solute", 0, 1, "T", "retention") volume (int): the volume id + export_unit (str): the unit of the derived quantity for exporting title (str): the title of the derived quantity show_units (bool): show the units in the title in the derived quantities file @@ -29,26 +30,30 @@ class TotalVolume(VolumeQuantity): def __init__(self, field, volume) -> None: super().__init__(field=field, volume=volume) + @property + def export_unit(self): + # obtain domain dimension + dim = self.function.function_space().mesh().topology().dim() + if self.field == "T": + if dim == 1: + return "K m" + if dim == 2: + return "K m2" + if dim == 3: + return "K m3" + else: + if dim == 1: + return "H m-2" + if dim == 2: + return "H m-1" + if dim == 3: + return "H" + @property def title(self): quantity_title = f"Total {self.field} volume {self.volume}" if self.show_units: - # obtain domain dimension - dim = self.function.function_space().mesh().topology().dim() - if self.field == "T": - if dim == 1: - return quantity_title + " (K m)" - elif dim == 2: - return quantity_title + " (K m2)" - elif dim == 3: - return quantity_title + " (K m3)" - else: - if dim == 1: - return quantity_title + " (H m-2)" - elif dim == 2: - return quantity_title + " (H m-1)" - elif dim == 3: - return quantity_title + " (H)" + return quantity_title + f" ({self.export_unit})" else: return quantity_title From 29e06c897dde6e2b344242191d785d43a7176a62 Mon Sep 17 00:00:00 2001 From: James Dark <65899899+jhdark@users.noreply.github.com> Date: Fri, 5 Apr 2024 06:14:56 +0000 Subject: [PATCH 16/20] changes from reveiw comments --- festim/exports/derived_quantities/average_volume.py | 2 +- festim/exports/derived_quantities/maximum_volume.py | 2 +- festim/exports/derived_quantities/minimum_volume.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/festim/exports/derived_quantities/average_volume.py b/festim/exports/derived_quantities/average_volume.py index 651751f70..9c4140161 100644 --- a/festim/exports/derived_quantities/average_volume.py +++ b/festim/exports/derived_quantities/average_volume.py @@ -5,7 +5,7 @@ class AverageVolume(VolumeQuantity): """ Computes the average value of a field in a given volume - int(f ds) / int (1 * ds) + int(f dx) / int (1 * dx) Args: field (str, int): the field ("solute", 0, 1, "T", "retention") diff --git a/festim/exports/derived_quantities/maximum_volume.py b/festim/exports/derived_quantities/maximum_volume.py index 62eee2100..7dc7f0b18 100644 --- a/festim/exports/derived_quantities/maximum_volume.py +++ b/festim/exports/derived_quantities/maximum_volume.py @@ -5,7 +5,7 @@ class MaximumVolume(VolumeQuantity): """ - Computes the maximum value in a field in a given volume + Computes the maximum value of a field in a given volume Args: field (str, int): the field ("solute", 0, 1, "T", "retention") diff --git a/festim/exports/derived_quantities/minimum_volume.py b/festim/exports/derived_quantities/minimum_volume.py index e3277c522..b11e6bb21 100644 --- a/festim/exports/derived_quantities/minimum_volume.py +++ b/festim/exports/derived_quantities/minimum_volume.py @@ -5,7 +5,7 @@ class MinimumVolume(VolumeQuantity): """ - Computes the minimum value in a field in a given volume + Computes the minimum value of a field in a given volume Args: field (str, int): the field ("solute", 0, 1, "T", "retention") From 1aac50327b33925bda38cd18bf9c73cc665cf028 Mon Sep 17 00:00:00 2001 From: James Dark <65899899+jhdark@users.noreply.github.com> Date: Sat, 6 Apr 2024 18:39:42 +0200 Subject: [PATCH 17/20] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: RĂ©mi Delaporte-Mathurin <40028739+RemDelaporteMathurin@users.noreply.github.com> --- festim/exports/derived_quantities/surface_flux.py | 14 ++------------ festim/exports/derived_quantities/total_surface.py | 14 ++------------ festim/exports/derived_quantities/total_volume.py | 14 ++------------ 3 files changed, 6 insertions(+), 36 deletions(-) diff --git a/festim/exports/derived_quantities/surface_flux.py b/festim/exports/derived_quantities/surface_flux.py index 33a6517d4..3c27d2a3e 100644 --- a/festim/exports/derived_quantities/surface_flux.py +++ b/festim/exports/derived_quantities/surface_flux.py @@ -41,19 +41,9 @@ def export_unit(self): # obtain domain dimension dim = self.function.function_space().mesh().topology().dim() if self.field == "T": - if dim == 1: - return "W m-2" - if dim == 2: - return "W m-1" - if dim == 3: - return "W" + return f"W m{dim-3}".replace(" m0", "") else: - if dim == 1: - return "H m-2 s-1" - if dim == 2: - return "H m-1 s-1" - if dim == 3: - return "H s-1" + return f"H m{dim-3} s-1".replace(" m0", "") @property def title(self): diff --git a/festim/exports/derived_quantities/total_surface.py b/festim/exports/derived_quantities/total_surface.py index 04a3a6a25..5eb9b8e25 100644 --- a/festim/exports/derived_quantities/total_surface.py +++ b/festim/exports/derived_quantities/total_surface.py @@ -35,19 +35,9 @@ def export_unit(self): # obtain domain dimension dim = self.function.function_space().mesh().topology().dim() if self.field == "T": - if dim == 1: - return "K" - if dim == 2: - return "K m" - if dim == 3: - return "K m2" + return f"K m{dim-1}".replace(" m0", "") else: - if dim == 1: - return "H m-2" - if dim == 2: - return "H m-1" - if dim == 3: - return "H" + return f"H m{dim-3}".replace(" m0", "") @property def title(self): diff --git a/festim/exports/derived_quantities/total_volume.py b/festim/exports/derived_quantities/total_volume.py index 141e8cada..56117c76e 100644 --- a/festim/exports/derived_quantities/total_volume.py +++ b/festim/exports/derived_quantities/total_volume.py @@ -35,19 +35,9 @@ def export_unit(self): # obtain domain dimension dim = self.function.function_space().mesh().topology().dim() if self.field == "T": - if dim == 1: - return "K m" - if dim == 2: - return "K m2" - if dim == 3: - return "K m3" + return f"K m{dim}".replace("1", "") else: - if dim == 1: - return "H m-2" - if dim == 2: - return "H m-1" - if dim == 3: - return "H" + return f"H m{dim-3}".replace(" m0", "") @property def title(self): From 62cf7193ee2ddf734c535a69830689bf87555e1f Mon Sep 17 00:00:00 2001 From: J Dark Date: Sat, 6 Apr 2024 18:47:38 +0200 Subject: [PATCH 18/20] added inline comment --- festim/exports/derived_quantities/surface_flux.py | 1 + festim/exports/derived_quantities/total_volume.py | 1 + 2 files changed, 2 insertions(+) diff --git a/festim/exports/derived_quantities/surface_flux.py b/festim/exports/derived_quantities/surface_flux.py index 3c27d2a3e..7c1d73c21 100644 --- a/festim/exports/derived_quantities/surface_flux.py +++ b/festim/exports/derived_quantities/surface_flux.py @@ -40,6 +40,7 @@ def __init__(self, field, surface) -> None: def export_unit(self): # obtain domain dimension dim = self.function.function_space().mesh().topology().dim() + # return unit depending on field and dimension of domain if self.field == "T": return f"W m{dim-3}".replace(" m0", "") else: diff --git a/festim/exports/derived_quantities/total_volume.py b/festim/exports/derived_quantities/total_volume.py index 56117c76e..164c55f54 100644 --- a/festim/exports/derived_quantities/total_volume.py +++ b/festim/exports/derived_quantities/total_volume.py @@ -34,6 +34,7 @@ def __init__(self, field, volume) -> None: def export_unit(self): # obtain domain dimension dim = self.function.function_space().mesh().topology().dim() + # return unit depending on field and dimension of domain if self.field == "T": return f"K m{dim}".replace("1", "") else: From 4f1e2c60bc8a7f9cb3a13f65e54bdfa879a925fd Mon Sep 17 00:00:00 2001 From: J Dark Date: Sat, 6 Apr 2024 18:47:57 +0200 Subject: [PATCH 19/20] comment and fix for m1 case --- festim/exports/derived_quantities/total_surface.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/festim/exports/derived_quantities/total_surface.py b/festim/exports/derived_quantities/total_surface.py index 5eb9b8e25..649c1308b 100644 --- a/festim/exports/derived_quantities/total_surface.py +++ b/festim/exports/derived_quantities/total_surface.py @@ -34,8 +34,9 @@ def __init__(self, field, surface) -> None: def export_unit(self): # obtain domain dimension dim = self.function.function_space().mesh().topology().dim() + # return unit depending on field and dimension of domain if self.field == "T": - return f"K m{dim-1}".replace(" m0", "") + return f"K m{dim-1}".replace(" m0", "").replace(" m1", " m") else: return f"H m{dim-3}".replace(" m0", "") From 04adb23b31f1c550d3125f9fd337093c67724b46 Mon Sep 17 00:00:00 2001 From: RemDelaporteMathurin Date: Thu, 18 Apr 2024 08:24:53 -0400 Subject: [PATCH 20/20] update to v4 on main --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a6da3054..d5bce7d4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,6 @@ jobs: pytest test/ --cov festim --cov-report xml --cov-report term - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }}