Esempio n. 1
0
    def argument(self, obj):
        Q = obj.ufl_function_space()
        dom = Q.ufl_domain()
        sub_elements = obj.ufl_element().sub_elements()

        # If not a mixed element, do nothing
        if (len(sub_elements) == 0):
            return obj

        # Split into sub-elements, creating appropriate space for each
        args = []
        for i, sub_elem in enumerate(sub_elements):
            Q_i = FunctionSpace(dom, sub_elem)
            a = Argument(Q_i, obj.number(), part=obj.part())

            indices = [()]
            for m in a.ufl_shape:
                indices = [(k + (j,)) for k in indices for j in range(m)]

            if (i == self.idx[obj.number()]):
                args += [a[j] for j in indices]
            else:
                args += [Zero() for j in indices]

        return as_vector(args)
Esempio n. 2
0
    def __init__(self, function_space, count=None):
        FormArgument.__init__(self)
        counted_init(self, count, Coefficient)

        if isinstance(function_space, FiniteElementBase):
            # For legacy support for .ufl files using cells, we map
            # the cell to The Default Mesh
            element = function_space
            domain = default_domain(element.cell())
            function_space = FunctionSpace(domain, element)
        elif not isinstance(function_space, AbstractFunctionSpace):
            error("Expecting a FunctionSpace or FiniteElement.")

        self._ufl_function_space = function_space
        self._ufl_shape = function_space.ufl_element().value_shape()

        self._repr = "Coefficient(%s, %s)" % (repr(
            self._ufl_function_space), repr(self._count))
Esempio n. 3
0
    def __init__(self, function_space, count=None):
        FormArgument.__init__(self)
        counted_init(self, count, Coefficient)

        if isinstance(function_space, FiniteElementBase):
            # For legacy support for .ufl files using cells, we map
            # the cell to The Default Mesh
            element = function_space
            domain = default_domain(element.cell())
            function_space = FunctionSpace(domain, element)
        elif not isinstance(function_space, AbstractFunctionSpace):
            error("Expecting a FunctionSpace or FiniteElement.")

        self._ufl_function_space = function_space
        self._ufl_shape = function_space.ufl_element().value_shape()

        self._repr = as_native_str("Coefficient(%s, %s)" % (
            repr(self._ufl_function_space), repr(self._count)))
Esempio n. 4
0
def TensorConstant(domain, shape=None, symmetry=None, count=None):
    """UFL value: Represents a globally constant tensor valued coefficient."""
    domain = as_domain(domain)
    element = TensorElement("Real",
                            domain.ufl_cell(),
                            0,
                            shape=shape,
                            symmetry=symmetry)
    fs = FunctionSpace(domain, element)
    return Coefficient(fs, count=count)
Esempio n. 5
0
    def __init__(self, function_space, number, part=None):
        FormArgument.__init__(self)

        if isinstance(function_space, FiniteElementBase):
            # For legacy support for UFL files using cells, we map the cell to
            # the default Mesh
            element = function_space
            domain = default_domain(element.cell())
            function_space = FunctionSpace(domain, element)
        elif not isinstance(function_space, AbstractFunctionSpace):
            error("Expecting a FunctionSpace or FiniteElement.")

        self._ufl_function_space = function_space
        self._ufl_shape = function_space.ufl_element().value_shape()

        if not isinstance(number, numbers.Integral):
            error("Expecting an int for number, not %s" % (number, ))
        if part is not None and not isinstance(part, numbers.Integral):
            error("Expecting None or an int for part, not %s" % (part, ))
        self._number = number
        self._part = part

        self._repr = "Argument(%s, %s, %s)" % (repr(
            self._ufl_function_space), repr(self._number), repr(self._part))
Esempio n. 6
0
    def __init__(self, function_space, number, part=None):
        FormArgument.__init__(self)

        if isinstance(function_space, FiniteElementBase):
            # For legacy support for .ufl files using cells, we map the cell to
            # the default Mesh
            element = function_space
            domain = default_domain(element.cell())
            function_space = FunctionSpace(domain, element)
        elif not isinstance(function_space, AbstractFunctionSpace):
            error("Expecting a FunctionSpace or FiniteElement.")

        self._ufl_function_space = function_space
        self._ufl_shape = function_space.ufl_element().value_shape()

        if not isinstance(number, numbers.Integral):
            error("Expecting an int for number, not %s" % (number,))
        if part is not None and not isinstance(part, numbers.Integral):
            error("Expecting None or an int for part, not %s" % (part,))
        self._number = number
        self._part = part

        self._repr = as_native_str("Argument(%s, %s, %s)" % (
            repr(self._ufl_function_space), repr(self._number), repr(self._part)))
Esempio n. 7
0
    def argument(self, obj):
        if (obj.part() is not None):
            # Mixed element built from MixedFunctionSpace,
            # whose sub-function spaces are indexed by obj.part()
            if len(obj.ufl_shape) == 0:
                if (obj.part() == self.idx[obj.number()]):
                    return obj
                else:
                    return Zero()
            else:
                indices = [()]
                for m in obj.ufl_shape:
                    indices = [(k + (j, )) for k in indices for j in range(m)]

                if (obj.part() == self.idx[obj.number()]):
                    return as_vector([obj[j] for j in indices])
                else:
                    return as_vector([Zero() for j in indices])
        else:
            # Mixed element built from MixedElement,
            # whose sub-elements need their function space to be created
            Q = obj.ufl_function_space()
            dom = Q.ufl_domain()
            sub_elements = obj.ufl_element().sub_elements()

            # If not a mixed element, do nothing
            if (len(sub_elements) == 0):
                return obj

            args = []
            for i, sub_elem in enumerate(sub_elements):
                Q_i = FunctionSpace(dom, sub_elem)
                a = Argument(Q_i, obj.number(), part=obj.part())

                indices = [()]
                for m in a.ufl_shape:
                    indices = [(k + (j, )) for k in indices for j in range(m)]

                if (i == self.idx[obj.number()]):
                    args += [a[j] for j in indices]
                else:
                    args += [Zero() for j in indices]

            return as_vector(args)
Esempio n. 8
0
def _handle_derivative_arguments(form, coefficient, argument):
    # Wrap single coefficient in tuple for uniform treatment below
    if isinstance(coefficient, (list, tuple, ListTensor)):
        coefficients = tuple(coefficient)
    else:
        coefficients = (coefficient,)

    if argument is None:
        # Try to create argument if not provided
        if not all(isinstance(c, Coefficient) for c in coefficients):
            error("Can only create arguments automatically for non-indexed coefficients.")

        # Get existing arguments from form and position the new one
        # with the next argument number
        if isinstance(form, Form):
            form_arguments = form.arguments()
        else:
            # To handle derivative(expression), which is at least used
            # in tests. Remove?
            form_arguments = extract_arguments(form)

        numbers = sorted(set(arg.number() for arg in form_arguments))
        number = max(numbers + [-1]) + 1

        # Don't know what to do with parts, let the user sort it out
        # in that case
        parts = set(arg.part() for arg in form_arguments)
        if len(parts - {None}) != 0:
            error("Not expecting parts here, provide your own arguments.")
        part = None

        # Create argument and split it if in a mixed space
        function_spaces = [c.ufl_function_space() for c in coefficients]
        domains = [fs.ufl_domain() for fs in function_spaces]
        elements = [fs.ufl_element() for fs in function_spaces]
        if len(function_spaces) == 1:
            arguments = (Argument(function_spaces[0], number, part),)
        else:
            # Create in mixed space over assumed (for now) same domain
            assert all(fs.ufl_domain() == domains[0] for fs in function_spaces)
            elm = MixedElement(*elements)
            fs = FunctionSpace(domains[0], elm)
            arguments = split(Argument(fs, number, part))
    else:
        # Wrap single argument in tuple for uniform treatment below
        if isinstance(argument, (list, tuple)):
            arguments = tuple(argument)
        else:
            n = len(coefficients)
            if n == 1:
                arguments = (argument,)
            else:
                if argument.ufl_shape == (n,):
                    arguments = tuple(argument[i] for i in range(n))
                else:
                    arguments = split(argument)

    # Build mapping from coefficient to argument
    m = {}
    for (c, a) in zip(coefficients, arguments):
        if c.ufl_shape != a.ufl_shape:
            error("Coefficient and argument shapes do not match!")
        if isinstance(c, Coefficient) or isinstance(c, SpatialCoordinate):
            m[c] = a
        else:
            if not isinstance(c, Indexed):
                error("Invalid coefficient type for %s" % ufl_err_str(c))
            f, i = c.ufl_operands
            if not isinstance(f, Coefficient):
                error("Expecting an indexed coefficient, not %s" % ufl_err_str(f))
            if not (isinstance(i, MultiIndex) and all(isinstance(j, FixedIndex) for j in i)):
                error("Expecting one or more fixed indices, not %s" % ufl_err_str(i))
            i = tuple(int(j) for j in i)
            if f not in m:
                m[f] = {}
            m[f][i] = a

    # Merge coefficient derivatives (arguments) based on indices
    for c, p in m.items():
        if isinstance(p, dict):
            a = zero_lists(c.ufl_shape)
            for i, g in p.items():
                set_list_item(a, i, g)
            m[c] = as_tensor(a)

    # Wrap and return generic tuples
    items = sorted(m.items(), key=lambda x: x[0].count())
    coefficients = ExprList(*[item[0] for item in items])
    arguments = ExprList(*[item[1] for item in items])
    return coefficients, arguments
Esempio n. 9
0
def VectorConstant(domain, dim=None, count=None):
    """UFL value: Represents a globally constant vector valued coefficient."""
    domain = as_domain(domain)
    element = VectorElement("Real", domain.ufl_cell(), 0, dim)
    fs = FunctionSpace(domain, element)
    return Coefficient(fs, count=count)
Esempio n. 10
0
def Constant(domain, count=None):
    """UFL value: Represents a globally constant scalar valued coefficient."""
    domain = as_domain(domain)
    element = FiniteElement("Real", domain.ufl_cell(), 0)
    fs = FunctionSpace(domain, element)
    return Coefficient(fs, count=count)