Reactive terms that depend on the value of the field variables and other condition

Hello everyone.

Let us suppose we have the following variational problem:

my problem is that I do not know how to define f(u). If it were completely smooth I would define it as:

u = Function(V)
w = TestFunction(V)
one = Constant(1.0)
u0 = Constant(u_0) #Given u_0 as a scalar value

f = one - u/u0

However, I do need it to behave different if u >u0.

I wrote this:

class chi(UserExpression):
    def __init__(self, Sat, **kwargs):
        super().__init__(**kwargs)
        # Selfs
        self.Sat = Sat
    def eval(self, values, var):
        Sat = self.Sat
        if var < Sat:
            values[0] = 1.0 - var/Sat
        else:
            values[0] = 0.0
    def value_shape(self):
        return ()

However, I do not know how to use it because I think if I set:

chi_1= chi(u_0)

and then try to use it in the variational form I think the input var will be the coordinate and not u.

Is there any way to input the value of u instead of the coordinates and so evaluate the function correctely?

You can use a conditional, see:

https://fenics.readthedocs.io/projects/ufl/en/latest/manual/form_language.html?highlight=Conditional%20#conditional

and

Thank you for your answer.

I think I understood the method and the code has no error. I have not finished it all so I do not know if I did it right. Anyway, this is part of what I wrote:

O2_H      = 7.00E+00 

P1 = FiniteElement('P', triangle, 2)
element = MixedElement([P1, P1, P1])
V = FunctionSpace(mesh, element)
W = FunctionSpace(mesh, P1)

u_1, u_2, u_3 = split(u)

U3_H = Constant(O2_H)
one = Constant(1.0)
zero = Constant(0.0)

chi_1_3 = project(Expression("0.0", degree=0), W)
chi_1_3_1 = one - u_3/U3_H
chi_1_3_2 = zero
chi_1_3.assign(project(conditional(le(u_3, O2_H), chi_1_3_1, chi_1_3_2), W))

I think I was making a big mistake since I created a new finite element space by:

W = FunctionSpace(mesh, P1)

and projecting over it, I have written the following hoping it would work

O2_H      = 7.00E+00 

P1 = FiniteElement('P', triangle, 2)
element = MixedElement([P1, P1, P1])
V = FunctionSpace(mesh, element)
V1 = V.sub(0)
V2 = V.sub(1)
V3 = V.sub(2)

u_1, u_2, u_3 = split(u)

U3_H = Constant(O2_H)
one = Constant(1.0)
zero = Constant(0.0)

chi_1_3 = project(Expression("0.0", degree=0), V3)
chi_1_3_1 = one - u_3/U3_H

However, it does not work and I have the following error:

*** Error: Unable to successfully call PETSc function ‘MatSetValuesLocal’.
*** Reason: PETSc error code is: 63 (Argument out of range).
*** Where: This error was encountered inside /build/dolfin-cZGj9S/dolfin-2019.2.0~git20200629.946dbd3/dolfin/la/PETScMatrix.cpp.

I think I misunderstand the meaning of V.sub(i), I though it would give me a subspace.

I have a system of reaction-diffusion equations with three variables, so how can I get the subspaces of each variable to project a function over a specific space?

You should collapse the sub space, project into the collapsed sub-space and use a FunctionAssigner as done in:

and
https://bitbucket.org/fenics-project/dolfin/raw/ec57db53f2b13f1768214829e8b4f80fc32205cf/python/demo/undocumented/sub-function-assignment/demo_sub-function-assignment.py