Skip to content

Commit

Permalink
Merge pull request #770 from RemDelaporteMathurin/temperature-as-float
Browse files Browse the repository at this point in the history
Temperature can be given as float or sp.Expr
  • Loading branch information
RemDelaporteMathurin authored Jun 5, 2024
2 parents fb2c99f + 6cb7559 commit 4573636
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 6 deletions.
18 changes: 13 additions & 5 deletions docs/source/userguide/temperature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ Temperature
===========

Definition of a temperature field or problem is essential for hydrogen transport
and FESTIM as a whole.
and FESTIM as a whole.
Regardless of how you define the temperature of the problem, it is passed to the :code:`T` attribute of the :class:`festim.Simulation` object.

----------------------
Analytical expressions
Expand All @@ -13,7 +14,7 @@ The temperature can be defined as a constant value in Kelvin (K):

.. code-block:: python
my_temperature = Temperature(value=300)
my_temperature = 300
Temperature can also be defined as an expression of time and/or space.
Expand All @@ -29,7 +30,7 @@ would be passed to FESTIM as:
from festim import x, t
my_temp = Temperature(300+2*x+3*t)
my_temp = 300 + 2*x + 3*t
More complex expressions can be expressed with sympy:

Expand All @@ -44,9 +45,16 @@ would be passed to FESTIM as:
from festim import x, t
import sympy as sp
my_temp = Temperature(sp.exp(x)*sp.sin(t))
my_temp = sp.exp(x) * sp.sin(t)
For more details, see :class:`festim.Temperature`.
Conditional expressions are also possible:

.. code-block:: python
from festim import x, t
import sympy as sp
my_temp = sp.Piecewise((400, F.t < 10), (300, True))
---------------------------
From a heat transfer solver
Expand Down
20 changes: 19 additions & 1 deletion festim/generic_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from festim.h_transport_problem import HTransportProblem
from fenics import *
import numpy as np
import sympy as sp
import warnings


Expand All @@ -25,7 +26,7 @@ class Simulation:
None.
settings (festim.Settings, optional): The model's settings.
Defaults to None.
temperature (festim.Temperature, optional): The model's
temperature (int, float, sympy.Expr, festim.Temperature, optional): The model's
temperature. Can be an expression or a heat transfer model.
Defaults to None.
initial_conditions (list of festim.InitialCondition, optional):
Expand Down Expand Up @@ -164,6 +165,23 @@ def exports(self, value):
"accepted types for exports are list, festim.Export or festim.Exports"
)

@property
def T(self):
return self._T

@T.setter
def T(self, value):
if isinstance(value, festim.Temperature):
self._T = value
elif value is None:
self._T = value
elif isinstance(value, (int, float, sp.Expr)):
self._T = festim.Temperature(value)
else:
raise TypeError(
"accepted types for T attribute are int, float, sympy.Expr or festim.Temperature"
)

def attribute_source_terms(self):
"""Assigns the source terms (in self.sources) to the correct field
(self.mobile, self.T, or traps)
Expand Down
52 changes: 52 additions & 0 deletions test/simulation/test_initialise.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import festim as F
from pathlib import Path
import pytest
import sympy as sp


def test_initialise_changes_nb_of_sources():
Expand Down Expand Up @@ -149,6 +150,42 @@ def test_cartesian_and_surface_flux_warning(quantity, sys):
my_model.initialise()


@pytest.mark.parametrize(
"value",
[
100,
0,
100.0,
0.0,
100 + 1 * F.x,
0 + 1 * F.x,
F.x,
F.t,
sp.Piecewise((400, F.t < 10), (300, True)),
],
)
def test_initialise_temp_as_number_or_sympy(value):
"""
Creates a Simulation object and checks that the T attribute
can be given as an int, a float or a sympy Expr
"""
# build
my_model = F.Simulation()
my_model.mesh = F.MeshFromVertices([1, 2, 3])
my_model.materials = F.Material(id=1, D_0=1, E_D=0)
my_model.T = value
my_model.settings = F.Settings(
absolute_tolerance=1e-10, relative_tolerance=1e-10, transient=False
)

# run
my_model.initialise()

# test
assert isinstance(my_model.T, F.Temperature)
assert my_model.T.value == value


def test_error_is_raised_when_no_temp():
"""
Creates a Simulation object and checks that an AttributeError is raised
Expand All @@ -170,6 +207,21 @@ def test_error_is_raised_when_no_temp():
my_model.initialise()


@pytest.mark.parametrize("value", ["coucou", [0, 0]])
def test_wrong_type_temperature(value):
"""
Creates a Simulation object and checks that a TypeError is raised
when the T attribute is given a value of the wrong type
"""
my_model = F.Simulation()

with pytest.raises(
TypeError,
match="accepted types for T attribute are int, float, sympy.Expr or festim.Temperature",
):
my_model.T = value


def test_error_raised_when_no_final_time():
"""
Creates a Simulation object and checks that a AttributeError is raised
Expand Down

0 comments on commit 4573636

Please sign in to comment.