def Arguments(function_space, number): """UFL value: Create an Argument in a mixed space, and return a tuple with the function components corresponding to the subelements.""" if isinstance(function_space, MixedFunctionSpace): return [Argument(function_space.ufl_sub_space(i), number, i) for i in range(function_space.num_sub_spaces())] else: return split(Argument(function_space, number))
def TrialFunctions(function_space): """Return a tuple of trial functions on the specified function space. :arg function_space: the :class:`.FunctionSpace` to build the trial functions on. This returns ``len(function_space)`` trial functions, which, if the function space is a :class:`.MixedFunctionSpace`, are indexed appropriately. """ return split(TrialFunction(function_space))
def Coefficients(function_space): """UFL value: Create a Coefficient in a mixed space, and return a tuple with the function components corresponding to the subelements.""" if isinstance(function_space, MixedFunctionSpace): return [ Coefficient(function_space.ufl_sub_space(i)) for i in range(function_space.num_sub_spaces()) ] else: return split(Coefficient(function_space))
def TestFunctions(function_space): """Return a tuple of test functions on the specified function space. :arg function_space: the :class:`.FunctionSpaceBase` to build the test functions on. This returns ``len(function_space)`` test functions, which, if the function space is a :class:`.MixedFunctionSpace`, are indexed appropriately. """ return split(TestFunction(function_space))
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
def TrialFunctions(element): """UFL value: Create a TrialFunction in a mixed space, and return a tuple with the function components corresponding to the subelements.""" return split(TrialFunction(element))
def Arguments(element): """UFL value: Create an Argument in a mixed space, and return a tuple with the function components corresponding to the subelements.""" return split(Argument(element))
def Coefficients(function_space): """UFL value: Create a Coefficient in a mixed space, and return a tuple with the function components corresponding to the subelements.""" return split(Coefficient(function_space))
def _handle_derivative_arguments(coefficient, argument): # Wrap single coefficient in tuple for uniform treatment below if isinstance(coefficient, (list,tuple)): 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.") elements = [c.element() for c in coefficients] if len(elements) > 1: elm = MixedElement(*elements) arguments = split(Argument(elm)) else: elm, = elements arguments = (Argument(elm),) 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.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 izip(coefficients, arguments): ufl_assert(c.shape() == a.shape(), "Coefficient and argument shapes do not match!") if isinstance(c, Coefficient): m[c] = a else: ufl_assert(isinstance(c, Indexed), "Invalid coefficient type for %s" % repr(c)) f, i = c.operands() ufl_assert(isinstance(f, Coefficient), "Expecting an indexed coefficient, not %s" % repr(f)) ufl_assert(isinstance(i, MultiIndex) and all(isinstance(j, FixedIndex) for j in i), "Expecting one or more fixed indices, not %s" % repr(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.iteritems(): if isinstance(p, dict): a = zero_lists(c.shape()) for i, g in p.iteritems(): 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 = Tuple(*[item[0] for item in items]) arguments = Tuple(*[item[1] for item in items]) return coefficients, arguments