sofia.pde package¶
Subpackages¶
Submodules¶
Module contents¶
- class sofia.pde.Del¶
Bases:
Basic- gradient(scalar_field, doit=False)¶
- dot(vect, doit=False)¶
- cross(vect, doit=False)¶
- default_assumptions = {}¶
- class sofia.pde.Derivative(expr, *variables, side: Literal['center', 'forward', 'backward'] = 'center', discretisation_order: int | None = None, allow_higher_order: bool = True, integer_stencils: bool | None = None, evaluate: bool = False, _order_explicit: bool | None = None, allow_expand: bool | None = None, _skip_sp=False, **kwargs)¶
Bases:
DerivativeA symbolic derivative class that extends
sympy.Derivative.This class extends
sympy.Derivativewith additional metadata for finite-difference discretisation. Supports stencil direction, order, and higher-order derivative handling.- Parameters:
expr – Expression to differentiate.
*variables – Variables and optional orders for differentiation.
side (Literal['center', 'forward', 'backward']) – Stencil direction for finite-difference approximation.
discretisation_order (int | None) – Accuracy order for finite-difference stencil.
allow_higher_order (bool) – Enable higher-order stencil use.
**kwargs – Additional keyword arguments passed to
sympy.Derivative.
- side: Literal['center', 'forward', 'backward']¶
- discretisation_order: int | None¶
- allow_higher_order: bool¶
- integer_stencils: bool | None¶
- allow_expand: bool | None¶
- expand_terms(evaluate=False)¶
Differentiate and attach metadata.
Apply SymPy’s differentiation rules (product/chain/.. etc.) and attach metadata to the resulting terms (cannot be passed through SymPys evaluation machinery).
- classmethod from_derivative(deriv)¶
- func(*args, **kwargs)¶
The top-level function in an expression.
The following should hold for all objects:
>> x == x.func(*x.args)
Examples
>>> from sympy.abc import x >>> a = 2*x >>> a.func <class 'sympy.core.mul.Mul'> >>> a.args (2, x) >>> a.func(*a.args) 2*x >>> a == a.func(*a.args) True
- as_finite_difference(points=None, lhs=None, wrt=None)¶
Return a finite-difference approximation of this derivative.
# See
pde.fdm.as_finite_difffor full documentation #
- default_assumptions = {}¶
- sofia.pde.as_finite_diff(expr, points=None, wrt=None, lhs=None, integer_stencils=None)¶
Compute a finite-difference approximation of a derivative.
This function returns a symbolic expression approximating a derivative of a function using a finite difference formula. The derivative is expressed as a weighted sum of the function evaluated at discrete points of the independent variable(s).
- Parameters:
expr – The derivative to approximate.
points –
If a sequence: the discrete values of the independent variable used to generate the finite difference weights (length >= order + 1).
If a scalar: treated as the step size to generate an equidistant sequence of length order + 1 centered around x0.
Default: 1 (unit step size).
lhs – Symbol of field representing the left-hand side, in which the result of the derivative is to be stored.
wrt – Variable with respect to which the derivative is taken. Required for partial derivatives if derivative is not ordinary. Default:
None.integer_stencils – Allows the use of optimised (integer stencils) or fall back to general stencils made from half-integer steps.
- Returns:
Symbolic expression representing the finite-difference approximation of the derivative, as a weighted sum of the function evaluated at discrete points.
- Return type:
sympy.Expr
See also
sympy.calculus.finite_diff.apply_finite_diff,sympy.calculus.finite_diff.finite_diff_weights
- sofia.pde.build_simulation(code_ir: CodegenAST, domain_specs: dict[Domain, Any], kernel_backend: KERNEL_NAMES | __annotationlib_name_1__ = 'auto', output_file: Path | None = None, overwrite: bool = False, return_module: bool = False, codegen_options: dict | None = None)¶
- sofia.pde.curl(vect, doit=True, allow_expand=None)¶
- sofia.pde.diff(expr: Expr, *symbols: Symbol, side: Literal['center', 'forward', 'backward'] = 'center', discretisation_order: int | None = None, allow_higher_order: bool = True, integer_stencils: bool | None = None, upwind: bool = False, evaluate: bool = True, physical: bool = False, allow_expand: bool | None = None, **kwargs) Expr¶
Differentiate expression with respect to one or more variables.
This is an extension of the
sympy.diffinterface that allows for more control over discretisation.- Parameters:
expr – Expression to be differentiated.
side – Specify stencil direction after discretisation.
center(default) corresponds to central difference,"forward"to forward differencing using points ahead, and"backward"to backward differencing using points behind the target location.discretisation_order – Specify stencil discretisation accuracy order.
allow_higher_order – If
True, stencils of higher differentiation order are used when possible. Otherwise higher-order derivatives are discretised as derivatives of derivatives.upwind – If
True, applies upwind differencing based on the sign of the expression.*symbols – See
sympy.difffor the interface.evaluate – Allows SymPy automatic evaluation.
integer_stencils – Allows the use of optimised (integer stencils) or fall back to general stencils made from half-integer steps.
physical – Take a derivative wrt the physical coordinates. This will insert lame coefficients, similar to the vector derivative operators.
allow_expand – If
True, product rule expansion is applied (before discretisation). The defaultNonetakes its value from thederivatives_allow_expandcontext var, which defaults toTrueand can be set from higher-level operators like gradient.**kwargs –
…
- Returns:
Derivative of
expr.- Return type:
sp.Expr
- sofia.pde.diff_finite(expr, wrt, order: int = 1, **kwargs) Expr¶
Discretised derivative with finite differences.
Equivalent to
discretise(diff(expr, coord, order)): it differentiates with respect to the coordinate of the requested dimension and immediately applies the finite-difference stencil.
- sofia.pde.diff_upwind(expr: Expr, *symbols: Symbol, variable: Expr | Symbol | None = None, eps: float = 1e-06, discretisation_order: int | None = None, upwind_discretisation_order: int | None = None, side: Literal['center', 'forward', 'backward'] = 'center', integer_stencils: bool | None = None, allow_expand: bool | None = None, **kwargs)¶
Return an upwind finite-difference approximation of a derivative.
The stencil selection is defined as:
forward difference if
expr < -epsbackward difference if
expr > epscentered difference otherwise
Forward and backward stencils by default use the same order as the centered stencil:
discretisation_order. This can be overridden by specifyingupwind_discretisation_order.- Parameters:
expr – Expression to differentiate. Its sign determines the upwind direction.
*symbols – One or more symbols with respect to which to differentiate.
variable – Expression whose sign determines the upwind direction. Defaults to
exprif not specified, i.e. the sign of the expression being differentiated.eps – Small tolerance used to determine the sign of
expr. Defaults to 1e-6.discretisation_order – Order of accuracy of the finite-difference stencil. Forward and backward stencils use one order lower. Defaults to 2.
upwind_discretisation_order – Order of accuracy of the forward and backward stencils. If not specified, defaults to
discretisation_order.side (
{'center', 'forward', 'backward'}, default ``’center’`) – Default stencil direction ifexpris withinepsof zero.integer_stencils – Allows the use of optimised (integer stencils) or fall back to general stencils made from half-integer steps.
allow_expand – If
True, product rule expansion is applied (before discretisation). The defaultNonetakes its value from thederivatives_allow_expandcontext var, which defaults toTrueand can be set from higher-level operators like gradient.**kwargs – Additional keyword arguments passed to
diff.
- Returns:
Symbolic finite-difference approximation using upwind stencil selection.
- Return type:
sp.Expr
Examples
>>> from sofia import Grid, Field >>> from sofia.pde import diff_upwind
>>> G = Grid(ndim=1) >>> u = Field("u", domain=G)
>>> diff_upwind(u, G.x) Piecewise( (Derivative(u, x, side='forward', discretisation_order=2), u < -1e-6), (Derivative(u, x, side='backward', discretisation_order=2), u > 1e-6), (Derivative(u, x, side='center', discretisation_order=2), True)
>>> diff_upwind(u, G.x, discretisation_order=4, upwind_discretisation_order=2) Piecewise( (Derivative(u, x, side='forward', discretisation_order=2), u < -1e-6), (Derivative(u, x, side='backward', discretisation_order=2), u > 1e-6), (Derivative(u, x, side='center', discretisation_order=4), True) )
- sofia.pde.discretise(expr, lhs=None)¶
- sofia.pde.divergence(vect, doit=True, allow_expand=None)¶
- sofia.pde.fix(code_ir: CodegenAST | __annotationlib_name_1__, domain_specs: dict[Domain, Any] | None = None)¶
- sofia.pde.gradient(field, doit=True, allow_expand=None)¶
- sofia.pde.laplacian(expr, allow_expand=None)¶
Return the laplacian of the given field.
It is computed in terms of the base scalars of the given coordinate system.
- Parameters:
expr – expr denotes a scalar or vector field.
allow_expand – Allows the expansion of product/chain rules.
- sofia.pde.rkn(F: dict[Field, sp.Expr], order: RK_ORDERS_OR_NAMES, dt: sp.Symbol, post: CodegenAST | None = None) RKn¶
Return a Runge-Kutta update scheme of the given update expressions.
- Parameters:
F – Mapping of fields to their time derivative expressions. Each entry
{u: expr}corresponds the equationdu/dt = expr.dt – Symbol representing the timestep in any of the given expressions.
order –
Runge-Kutta order or scheme name. Supported values include:
Integer orders: 1, 2, 3, 4
Named schemes: “euler”, “midpoint”, “heun2”, “ralston2”, “kutta3”, “heun3”, “ralston3”, “SSPRK3”, “3/8”, “m2s2”
post – Optional extra IR that should be appended to each RK stage. Any appearance of
dtin this IR will be adjusted to the total timestep of the stage.
- Returns:
IR token representing the Runge-Kutta integration scheme, which can be expanded by calling .doit().
- Return type:
rkn_token
- sofia.pde.simulate(code_ir: CodegenAST, domain_specs: dict[Domain, Any], *inputs, kernel_backend: KERNEL_NAMES | __annotationlib_name_1__ = 'auto', output_file: Path | None = None, overwrite: bool = False, codegen_options: dict | None = None)¶
- sofia.pde.eval_expr(expr: EvalAssignment, domain_specs, kernel_backend='auto', cse: bool = True, show=False, strict_inputs=False, **inputs)¶
- sofia.pde.apply_boundary_conditions(conditions: tuple[tuple[Expr, Expr], ...] | tuple[Expr, Expr] | tuple[BoundarySpec, ...] | BoundarySpec, field: Field | None = None, extrapolation_order: int = 1, base_expr: Expr | None = None, as_eval_assignment: bool = False) __annotationlib_name_1__ | CodegenAST¶
Augment Field with interpolations that satisfy given boundary conditions.
- Parameters:
conditions – Boundary condition specifiers from which the interpolations are determined. Either tuples of Sympy expressions, or dicts of type BoundarySpec.
field – Input Field to which boundary conditions should be applied.
extrapolation_order – Order of extrapolation polynomial (affects the number of Field values used).
base_expr – Optional expression that replaces the Field in the non-interpolated region. This can be used to make a general expression for the interior of the domain while switching to extrapolations of a (different) Field at the boundaries.
as_eval_assignment – If True, return an ir.EvalAssignment instead of a Sympy expression.
- Returns:
Piecewise expression that contains additional clauses for boundary conditions.
- Return type:
sp.Expr