Update time-dependent expression in PDE

Hi everyone, I am new to fenics and I wonder if you can kindly help me on the problem.

I am trying to solve a time-dependent PDE where in the rhs there are some time-dependent coefficients. For simplicity, lets say the equation is:

\frac{\partial u}{\partial t} = f(t)\frac{\partial u}{\partial x}

where f(t) is a time dependent scalar function. I start this project by using a constant first, f(t) = const and everything is fine. Now I am considering the actual time-dependent f(t), I wonder how to do this. In my opinion, I am thinking to change the expression at each iteration in solving the PDE (assuming f(t) = sin(\omega t)):

# here just ignore the actual variational formulation of the PDE, I just wonder how to update with t
f_t = Expression('sin(omega t) * x[0]' , omega=1, t=0))
...
for n in range(1, max_step):
   t += dt
   u_D.t = t
    f_t.user_paremeters['t'] = t
    # a and L are lhs and rhs of the PDE
    solve(a == L, u)

I doubt whether this will update the f_t expression actually. I read from this link:

possibly I can use a self-defined UserExpression, but this is extremely slow on my machine. I wonder what is the simplest way to do this, since my expression is constant on the whole mesh but only dependent on time.

Thanks in advance for any help!

If the expression is constant on the whole mesh, you can use a Constant and update it using assign, e.g.

f_t = Constant(0)
omega = 1
...
for n in range(1, max_step):
    t += dt
    u_D.t = t
    f_t.assign(np.sin(omega*t))
    # a and L are lhs and rhs of the PDE
    solve(a == L, u)
1 Like

Hi @conpierce8 , thanks for your reply. However in my problem the whole expression is not independent over the mesh, but some coefficients in the expression only depends on time, e.g.

f_t = Expression('sin(omega * t) * x[0]', omega=1, t=0)

where the term sin(\omega t) only depends on time but the whole expression is different through the mesh. I wonder if there is a update method to do so, something like

for for n in range(1, max_step):
    t += dt
    u_D.t = t
    f_t.update(t) # does this work?
    # a and L are lhs and rhs of the PDE
    solve(a == L, u)

Thanks for your help again and look forward to hearing from you.

Hi @Zhuonan_Lin,

The Expression has instance variables (e.g. f_t.omega, f_t.t) which you can use to update the values of the parameters, i.e.:

from fenics import *

f_t = Expression("sin(omega*t) * x[0]", degree=1, omega=1, t=0)

t = 0
dt = 0.1
for i in range(10):
    print(f_t([0.5, 0.5]))
    
    t += dt
    f_t.t = t
1 Like