Finite Differences

class Diff

Sympy Node representing a derivative.

The difference to sympy’s built in differential is:
  • shortened latex representation

  • all simplifications have to be done manually

  • optional marker displayed as superscript

get_arg_recursive()

Returns the argument the derivative acts on, for nested derivatives the inner argument is returned

change_arg_recursive(new_arg)

Returns a Diff node with the given ‘new_arg’ instead of the current argument. For nested derivatives a new nested derivative is returned where the inner Diff has the ‘new_arg’

split_linear(functions)

Applies linearity property of Diff: i.e. ‘Diff(c*a+b)’ is transformed to ‘c * Diff(a) + Diff(b)’ The parameter functions is a list of all symbols that are considered functions, not constants. For the example above: functions=[a, b]

property arg

Expression the derivative acts on

property target

Subscript, usually the variable the Diff is w.r.t.

property superscript

Superscript, for example used as the Chapman-Enskog order index

class DiffOperator

Un-applied differential, i.e. differential operator

Parameters
  • target – the differential is w.r.t to this variable. This target is mainly for display purposes (its the subscript) and to distinguish DiffOperators If the target is ‘-1’ no subscript is displayed

  • superscript – optional marker displayed as superscript is not displayed if set to ‘-1’

The DiffOperator behaves much like a variable with special name. Its main use is to be applied later, using the DiffOperator.apply(expr, arg) which transforms ‘DiffOperator’s to applied ‘Diff’s

static apply(expr, argument, apply_to_constants=True)

Returns a new expression where each ‘DiffOperator’ is replaced by a ‘Diff’ node. Multiplications of ‘DiffOperator’s are interpreted as nested application of differentiation: i.e. DiffOperator(‘x’)*DiffOperator(‘x’) is a second derivative replaced by Diff(Diff(arg, x), t)

collect_diffs(expr)

Rewrites expression into a sum of distinct derivatives with pre-factors

combine_diff_products(expr)

Inverse product rule

diff(expr, *args)

Shortcut function to create nested derivatives

>>> f = sp.Symbol("f")
>>> diff(f, 0, 0, 1) == Diff(Diff( Diff(f, 1), 0), 0)
True
diff_terms(expr)

Returns set of all derivatives in an expression.

This function yields different results than ‘expr.atoms(Diff)’ when nested derivatives are in the expression, since this function only returns the outer derivatives

Example

>>> x, y = sp.symbols("x, y")
>>> diff_terms( diff(x, 0, 0)  )
{Diff(Diff(x, 0, -1), 0, -1)}
evaluate_diffs(expr, var=None)

Replaces pystencils diff objects by sympy diff objects and evaluates them.

Replaces Diff nodes by sp.diff , the free variable is either the target (if var=None) otherwise the specified var

expand_diff_linear(expr, functions=None, constants=None)

Expands all derivative nodes by applying Diff.split_linear

Parameters
  • expr – expression containing derivatives

  • functions – sequence of symbols that are considered functions and can not be pulled before the derivative. if None, all symbols are viewed as functions

  • constants – sequence of symbols which are considered constants and can be pulled before the derivative

expand_diff_products(expr)

Fully expands all derivatives by applying product rule

functional_derivative(functional, v)

Computes functional derivative of functional with respect to v using Euler-Lagrange equation

\[\frac{\delta F}{\delta v} = \frac{\partial F}{\partial v} - \nabla \cdot \frac{\partial F}{\partial \nabla v}\]
  • assumes that gradients are represented by Diff() node

  • Diff(Diff(r)) represents the divergence of r

  • the constants parameter is a list with symbols not affected by the derivative. This is used for simplification of the derivative terms.

normalize_diff_order(expression, functions=None, constants=None, sort_key=<function _default_diff_sort_key>)

Assumes order of differentiation can be exchanged. Changes the order of nested Diffs to a standard order defined by the sorting key ‘sort_key’ such that the derivative terms can be further simplified

zero_diffs(expr, label)

Replaces all differentials with the given target by 0

Example

>>> x, y, f = sp.symbols("x y f")
>>> expression = Diff(f, x) + Diff(f, y) + Diff(Diff(f, y), x) + 7
>>> zero_diffs(expression, x)
Diff(f, y, -1) + 7
advection(advected_scalar, velocity_field, idx=None)

Advection term ∇·(velocity_field · advected_scalar)

Term that describes the advection of a scalar quantity in a velocity field.

diffusion(scalar, diffusion_coeff, idx=None)

Diffusion term ∇·( diffusion_coeff · ∇(scalar))

Examples

>>> f = Field.create_generic('f', spatial_dimensions=2)
>>> diffusion_term = diffusion(scalar=f, diffusion_coeff=sp.Symbol("d"))
>>> discretization = Discretization2ndOrder()
>>> discretization(diffusion_term)
(f_W*d + f_S*d - 4*f_C*d + f_N*d + f_E*d)/dx**2
transient(scalar, idx=None)

Transient term ∂_t(scalar)