sofia.field.field¶
- class sofia.field.field.Field(name, domain, *args, **kwargs)¶
Bases:
ExprSymbolic field living on
Domain.- as_dummy(name=None)¶
Return the expression with any objects having structurally bound symbols replaced with unique, canonical symbols within the object in which they appear and having only the default assumption for commutativity being True. When applied to a symbol a new symbol having only the same commutativity will be returned.
Examples
>>> from sympy import Integral, Symbol >>> from sympy.abc import x >>> r = Symbol('r', real=True) >>> Integral(r, (r, x)).as_dummy() Integral(_0, (_0, x)) >>> _.variables[0].is_real is None True >>> r.as_dummy() _r
Notes
Any object that has structurally bound variables should have a property,
bound_symbolsthat returns those symbols appearing in the object.
- class sofia.field.field.VectorField(name: str | Symbol, domain: Domain, staggered: str | tuple[Staggered, ...] | None = None, **kwargs)¶
- class sofia.field.field.VectorField(*terms: Vector, **options)
Bases:
VectorAddA vector field composed of one scalar Field per axis.
It is a sympy vector so it can be used in any vector expression.
- Parameters:
name – Each component field is named f”{name}_{axis}” (where axis is “x”, “y” or “z”).
domain – Domain the component fields live on.
staggered – Where the components sit within a cell on a Grid. This can be given either as a Staggered per component or as the string “faces”, which means each component lives on the face normal to its axis.
**kwargs – Forwarded to every component Field.
Examples
>>> from sofia import Grid >>> G = Grid(ndim=2, name="G") >>> u = VectorField("u", G) >>> u u_x*global.ihat + u_y*global.jhat >>> u.fields (u_x, u_y) >>> [f.staggered for f in VectorField("m", G, staggered="faces").fields] [XFACE, YFACE] >>> u << 0 CodeBlock( EvalAssignment(u_x, 0), EvalAssignment(u_y, 0) )
- class sofia.field.field.TensorField(name: str | Symbol, domain: Domain, symmetric: bool = False, staggered: str | tuple[tuple[Staggered | None, ...], ...] | None = None, **kwargs)¶
- class sofia.field.field.TensorField(*terms: Dyadic, **options)
Bases:
DyadicAddAn order 2 tensor field (dyadic) composed of one scalar Field per pair of axes.
It is a sympy dyadic, so it can be used in any dyadic expression.
- Parameters:
name – Each component field is named f”{name}_{a}{b}” (e.g. T_xy).
domain – Domain the component fields live on.
symmetric – Use one field for T_ab and T_ba, so the tensor is symmetric by construction.
staggered – Where the components sit within a cell on a Grid. This can be given either as one Staggered per component, as rows (staggered[a][b] for component T_ab), or as the string “mac”, which puts the diagonal components at cell centers and the off-diagonal ones on the edges.
**kwargs – Forwarded to every component Field.
Examples
>>> from sofia import Grid >>> G = Grid(ndim=2, name="G") >>> T = TensorField("T", G) >>> T.fields (T_xx, T_xy, T_yx, T_yy) >>> T.dot(G.unit_vectors[0]) T_xx*global.ihat + T_yx*global.jhat >>> S = TensorField("S", G, symmetric=True) >>> S.fields (S_xx, S_xy, S_yy) >>> S << 2 CodeBlock( EvalAssignment(S_xx, 2), EvalAssignment(S_xy, 2), EvalAssignment(S_yy, 2) )
- property symmetric: bool¶
Whether T_ab and T_ba are the same field for every pair of axes.
- sofia.field.field.component_fields(symbols) tuple¶
Return symbols as a tuple, with vector and tensor fields split into fields.
- sofia.field.field.fields(names: str, domain: Domain, **kwargs: object) tuple[Field, ...]¶
Create one or more Fields on a shared domain.
Equivalent to
sympy.symbols(), but for Fields. Always returns a tuple for better type support.- Parameters:
names – Field names, comma- or whitespace-separated; see
sympy.symbols().domain – Domain the fields live on.
**kwargs – Forwarded to the Field subclass registered for
domain.
- Returns:
A tuple of the created Field(s).
- Return type:
tuple[Field, …]
Examples
>>> (u,) = fields("u", domain=Grid(ndim=1)) >>> v, w = fields("v w", domain=Grid(ndim=2))