Inhomogeneous Dirichlet BC from csv file

@ehodille I also took the opportunity to adapt this example to a temperature field from a list of points.

import festim as F
import fenics as f
import numpy as np

my_model = F.Simulation()

my_model.mesh = F.MeshFromVertices(np.linspace(0, 1))
my_model.materials = F.Material(id=1, D_0=1e-7, E_D=0.2)


class InterpolatedExpression(f.UserExpression):
    def __init__(self, f):
        super().__init__()
        self.f = f
        self.t = 0

    def eval(self, value, x):
        value[0] = self.f(self.t)


class TFromData(F.Temperature):
    def __init__(self, f):
        value = InterpolatedExpression(f)
        super().__init__(value)

    # override the create_functions method
    def create_functions(self, mesh):
        """Creates functions self.T, self.T_n

        Args:
            mesh (festim.Mesh): the mesh
        """
        V = f.FunctionSpace(mesh.mesh, "CG", 1)
        self.T = f.Function(V, name="T")
        self.T_n = f.Function(V, name="T_n")
        self.expression = self.value
        self.T.assign(f.interpolate(self.expression, V))
        self.T_n.assign(self.T)


from scipy.interpolate import interp1d
import numpy as np

# your data
t = np.linspace(0, 10, num=10000)
T = 300 + np.sin(2 * np.pi * t)
T_f = interp1d(t, T)

my_model.T = TFromData(T_f)


my_model.boundary_conditions = [
    F.DirichletBC(surfaces=[1], value=1, field=0),
]

my_model.settings = F.Settings(
    absolute_tolerance=1e-1, relative_tolerance=1e-10, transient=True, final_time=10
)

my_model.dt = F.Stepsize(0.01)
my_model.exports = [F.DerivedQuantities([F.AverageVolume("T", volume=1)])]

my_model.initialise()

my_model.run()

import matplotlib.pyplot as plt

T_t = my_model.exports[-1][0].t
T_values = my_model.exports[-1][0].data
plt.plot(T_t, T_values)
plt.xlabel("Time")
plt.ylabel("Temperature")
plt.show()

Which produces:

This way you could use the experimental T measurement in TDS simulations for instance.

# your data
t = np.linspace(0, 100, num=10000)

T = np.zeros_like(t)  # create array full of zeros

t_tds = 50
T[t < t_tds] = 300  # set values for t < t_tds
ramp = 2
T[t >= t_tds] = 300 + ramp * (t[t >= t_tds] - t_tds)  # set values for t >= t_tds

# interpolate the data
T_f = interp1d(t, T)

my_model.T = TFromData(T_f)