Esempio n. 1
0
    def __new__(cls, expr, *dims, **kwargs):
        if type(expr) == sympy.Derivative:
            raise ValueError(
                "Cannot nest sympy.Derivative with devito.Derivative")
        if not isinstance(expr, Differentiable):
            raise ValueError("`expr` must be a Differentiable object")

        new_dims, orders, fd_o, var_count = cls._process_kwargs(
            expr, *dims, **kwargs)

        # Construct the actual Derivative object
        obj = Differentiable.__new__(cls, expr, *var_count)
        obj._dims = tuple(OrderedDict.fromkeys(new_dims))

        skip = kwargs.get('preprocessed', False) or obj.ndims == 1

        obj._fd_order = fd_o if skip else DimensionTuple(*fd_o,
                                                         getters=obj._dims)
        obj._deriv_order = orders if skip else DimensionTuple(
            *orders, getters=obj._dims)
        obj._side = kwargs.get("side")
        obj._transpose = kwargs.get("transpose", direct)
        obj._ppsubs = as_tuple(frozendict(i) for i in kwargs.get("subs", []))
        obj._x0 = frozendict(kwargs.get('x0', {}))
        return obj
Esempio n. 2
0
    def __new__(cls, expr, *dims, **kwargs):
        if type(expr) == sympy.Derivative:
            raise ValueError(
                "Cannot nest sympy.Derivative with devito.Derivative")
        if not isinstance(expr, Differentiable):
            raise ValueError("`expr` must be a Differentiable object")

        # Check `dims`. It can be a single Dimension, an iterable of Dimensions, or even
        # an iterable of 2-tuple (Dimension, deriv_order)
        if len(dims) == 0:
            raise ValueError(
                "Expected Dimension w.r.t. which to differentiate")
        elif len(dims) == 1:
            if isinstance(dims[0], Iterable):
                # Iterable of Dimensions
                if len(dims[0]) != 2:
                    raise ValueError("Expected `(dim, deriv_order)`, got %s" %
                                     dims[0])
                orders = kwargs.get('deriv_order', dims[0][1])
                if dims[0][1] != orders:
                    raise ValueError("Two different values of `deriv_order`")
                new_dims = tuple([dims[0][0]] * dims[0][1])
            else:
                # Single Dimension
                orders = kwargs.get('deriv_order', 1)
                if isinstance(orders, Iterable):
                    orders = orders[0]
                new_dims = tuple([dims[0]] * orders)
        else:
            # Iterable of 2-tuple, e.g. ((x, 2), (y, 3))
            new_dims = []
            orders = []
            d_ord = kwargs.get('deriv_order', tuple([1] * len(dims)))
            for d, o in zip(dims, d_ord):
                if isinstance(d, Iterable):
                    new_dims.extend([d[0] for _ in range(d[1])])
                    orders.append(d[1])
                else:
                    new_dims.extend([d for _ in range(o)])
                    orders.append(o)
            new_dims = as_tuple(new_dims)
            orders = as_tuple(orders)

        # Finite difference orders depending on input dimension (.dt or .dx)
        fd_orders = kwargs.get(
            'fd_order',
            tuple([
                expr.time_order
                if getattr(d, 'is_Time', False) else expr.space_order
                for d in dims
            ]))
        if len(dims) == 1 and isinstance(fd_orders, Iterable):
            fd_orders = fd_orders[0]

        # SymPy expects the list of variable w.r.t. which we differentiate to be a list
        # of 2-tuple `(s, count)` where s is the entity to diff wrt and count is the order
        # of the derivative
        variable_count = [
            sympy.Tuple(s, new_dims.count(s)) for s in filter_ordered(new_dims)
        ]

        # Construct the actual Derivative object
        obj = Differentiable.__new__(cls, expr, *variable_count)
        obj._dims = tuple(OrderedDict.fromkeys(new_dims))
        obj._fd_order = fd_orders
        obj._deriv_order = orders
        obj._side = kwargs.get("side", centered)
        obj._transpose = kwargs.get("transpose", direct)
        obj._subs = as_tuple(kwargs.get("subs"))
        obj._x0 = kwargs.get('x0', None)
        return obj