Hello, FEniCS community,
I am stuck with what seems to be a very simple problem. I have a dynamic simulation (with 6 PDEs), and for some numerical reasons, I am obtaining negative values within my solution (u). I need to force the solution to be non-negative. That is, if there is any negative value within the spatial function, it must be transformed into zero. For this purpose, I am using UFL conditionals as shown below. However, I get the following error:
Expecting scalar arguments.
Traceback (most recent call last):
File “Variational_Problem_EF.py”, line 284, in SafeU
return conditional(gt(x, DOLFIN_EPS), x, DOLFIN_EPS)
ufl.log.UFLException: Expecting scalar arguments.
So I also tried to split u into each of the six Finite element solutions suchlike:
u_1, u_2, u_3, u_4, u_5, u_6 = split(u)
conditional(gt(u_1, DOLFIN_EPS), u_1, DOLFIN_EPS)
conditional(gt(u_2, DOLFIN_EPS), u_2, DOLFIN_EPS)
conditional(gt(u_3, DOLFIN_EPS), u_3, DOLFIN_EPS)
...
However, it seems that each of these lines of code create a C++ expression. Further, these expressions must be compiled to actually update the solution by eliminating all negative values to zeros.
I post an exemplification of the code, notwithstanding, it cannot be executed, it is only aimed to facilitate the explanation above.
P1 = FiniteElement('P', triangle, 1)
element = MixedElement([P1, P1, P1, P1, P1, P1])
V = FunctionSpace(mesh, element)
# Define test functions
v_1, v_2, v_3, v_4, v_5, v_6 = TestFunctions(V)
# Define functions for concentrations and temperature
u = Function(V)
u_n = Function(V)
# Split system functions to access components
u_n1, u_n2, u_n3, u_n4, u_n5, u_n6 = split(u_n)
u_1, u_2, u_3, u_4, u_5, u_6 = split(u)
# Variational formulation
F = ...
for n in range(num_steps):
t += deltaT # Update current time
solve(F == 0, u, bcs, solver_parameters={"newton_solver": {"relative_tolerance": 1e-5}})
def Non_zeroU(x):
return conditional(gt(x, DOLFIN_EPS), x, DOLFIN_EPS)
u_n.assign(Non_zeroU(u))
Thank you so much for any suggestions or comments on this topic.
All the best,
Santiago