The source term f is described by the following equation:
\frac{d}{dt}f(t) = \sqrt{f(t)} * \left ( constant - u_{average\;of\;a\;facet}(x_1,t) \right ),
where u_{average\;of\;a\;facet}(x_1,t) is the average value of u of one of the facets of the domain. Because I currently don‘t know how the average value of a facet is calculated in Fenics, I used the average of u of the whole domain as a dummy value to realize the minimum working code example (MWCE).
The minimum working code example is based on the ft03_heat.py tutorial, which explains a time dependent poisson equation and is governed by the following equations:
{u}'=\Delta u + f \;\;\; in the unit square
u = u_D \;\;\;\;\;\;\;\;\;\;\; on the boundary (Dirichlet boundary conditions)
u = u_0 \;\;\;\;\;\;\;\;\;\;\;\; at t = 0
So, how do I implement the equation of the source term f in Fenics, without using additional software?
Or, in other words, how do I replace the pseudo code in the MWCE underneath with real Fenics code?
from __future__ import print_function
from fenics import *
T = 2.0 # final time
num_steps = 10 # number of time steps
dt = T / num_steps # time step size
alpha = 3 # parameter alpha
beta = 1.2 # parameter beta
constant = 5 # known Constant to calculate f
# Create mesh and define function space
nx = ny = 8
mesh = UnitSquareMesh(nx, ny)
V = FunctionSpace(mesh, 'P', 1)
# Define boundary condition
u_D = Expression('1 + x[0]*x[0] + alpha*x[1]*x[1] + beta*t',
degree=2, alpha=alpha, beta=beta, t=0)
def boundary(x, on_boundary):
return on_boundary
bc = DirichletBC(V, u_D, boundary)
# Define initial value
u_n = interpolate(u_D, V)
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = 3 # known initial condition of f: f(t=0) = 3
F = u*v*dx + dt*dot(grad(u), grad(v))*dx - (u_n + dt*f)*v*dx
a, L = lhs(F), rhs(F)
# Time-stepping
u = Function(V)
t = 0
for n in range(num_steps):
# Update current time
t += dt
u_D.t = t
# Calculate average u of the domain instead of calculate the average of a facet
vertex_values_u = u.compute_vertex_values(mesh)
avg_u = np.average(vertex_values_u)
# Pseudo code to calculate f for the current time step
equation = df/dt - sqrt(f) * (constant - avg_u) == 0
f = solve(equation, bc = f_0)
# Compute solution
solve(a == L, u, bc)
# Plot solution
plot(u)
# Update previous solution
u_n.assign(u)
# Hold plot
interactive()
Thanks,
Jan