Symbolic operator representation¶
Based on pymbolic
.
Basic objects¶
Object types¶
Based on the mathematical quantity being represented, the following types of objects occur as part of a symbolic operator representation:
If a quantity is a scalar, it is just a symbolic expression–that is, an element of the set of formal expressions recursively generated by the placeholders (see Placeholders), constants, and arithmetic operations on them (see
pymbolic.primitives
). Objects of this type are created simply by doing arithmetic on placeholders and scalar constants.If the quantity is “just a bunch of scalars” (like, say, rows in a system of integral equations), the symbolic representation is an object array. Each element of the object array contains a symbolic expression.
pytools.obj_array.make_obj_array()
andpytools.obj_array.flat_obj_array()
can help create those.If it is a geometric quantity (that makes sense without explicit reference to coordinates), it is a
pymbolic.geometric_algebra.MultiVector
. This can be converted to an object array by calling:pymbolic.geometric_algebra.MultiVector.as_vector()
.
pyopencl.array.Array
and meshmode.dof_array.DOFArray
instances
hold per-node degrees of freedom (and only those). Such instances do not occur
on the symbolic side of pytential
at all. They’re only visible either as
bound inputs (see pytential.bind()
) or outputs of evaluation. Which one is
used depends on the meaning of the data being represented. If the data is
associated with a Discretization
, then
DOFArray
is used and otherwise
Array
is used.
DOF Description¶
- class pytential.symbolic.primitives.QBX_SOURCE_STAGE1[source]¶
Symbolic identifier for the Stage 1 discretization of a
pytential.qbx.QBXLayerPotentialSource
.
- class pytential.symbolic.primitives.QBX_SOURCE_STAGE2[source]¶
Symbolic identifier for the Stage 2 discretization of a
pytential.qbx.QBXLayerPotentialSource
.
- class pytential.symbolic.primitives.QBX_SOURCE_QUAD_STAGE2[source]¶
Symbolic identifier for the upsampled Stage 2 discretization of a
pytential.qbx.QBXLayerPotentialSource
.
- class pytential.symbolic.primitives.GRANULARITY_CENTER[source]¶
DOFs interleaved per expansion center (two per node, one on each side).
- class pytential.symbolic.primitives.DOFDescriptor(geometry=None, discr_stage=None, granularity=None)[source]¶
A data structure specifying the meaning of a vector of degrees of freedom that is handled by
pytential
(a “DOF vector”). In particular, usinggeometry
, this data structure describes the geometric object on which the (scalar) function described by the DOF vector exists. Usinggranularity
, the data structure describes how the geometric object is discretized (e.g. conventional nodal data, per-element scalars, etc.)- geometry¶
An identifier for the geometry on which the DOFs exist. This can be a simple string or any other hashable identifier for the geometric object. The geometric objects are generally subclasses of
PotentialSource
,TargetBase
orDiscretization
.
- discr_stage¶
Specific to a
pytential.source.LayerPotentialSourceBase
, this describes on which of the discretizations the DOFs are defined. Can be one ofQBX_SOURCE_STAGE1
,QBX_SOURCE_STAGE2
orQBX_SOURCE_QUAD_STAGE2
.
- granularity¶
Describes the level of granularity of the DOF vector. Can be one of
GRANULARITY_NODE
(one DOF per node),GRANULARITY_CENTER
(two DOFs per node, one per side) orGRANULARITY_ELEMENT
(one DOF per element).
Placeholders¶
- pytential.symbolic.primitives.var[source]¶
alias of
pymbolic.primitives.Variable
Functions¶
- pytential.symbolic.primitives.real¶
- pytential.symbolic.primitives.imag¶
- pytential.symbolic.primitives.conj¶
- pytential.symbolic.primitives.abs¶
- pytential.symbolic.primitives.sqrt¶
- pytential.symbolic.primitives.sin¶
- pytential.symbolic.primitives.cos¶
- pytential.symbolic.primitives.tan¶
- pytential.symbolic.primitives.asin¶
- pytential.symbolic.primitives.acos¶
- pytential.symbolic.primitives.atan¶
- pytential.symbolic.primitives.atan2¶
- pytential.symbolic.primitives.sinh¶
- pytential.symbolic.primitives.cosh¶
- pytential.symbolic.primitives.tanh¶
- pytential.symbolic.primitives.asinh¶
- pytential.symbolic.primitives.acosh¶
- pytential.symbolic.primitives.atanh¶
- pytential.symbolic.primitives.exp¶
- pytential.symbolic.primitives.log¶
Discretization properties¶
- class pytential.symbolic.primitives.QWeight(dofdesc=None)[source]¶
Bare quadrature weights (without Jacobians).
- pytential.symbolic.primitives.nodes(ambient_dim, dofdesc=None)[source]¶
Return a
pymbolic.geometric_algebra.MultiVector
of node locations.
- pytential.symbolic.primitives.parametrization_derivative(ambient_dim, dim, dofdesc=None)[source]¶
Return a
pymbolic.geometric_algebra.MultiVector
representing the derivative of the reference-to-global parametrization.
- pytential.symbolic.primitives.parametrization_derivative_matrix(ambient_dim, dim, dofdesc=None)[source]¶
Return a
numpy.ndarray
representing the derivative of the reference-to-global parametrization.
- pytential.symbolic.primitives.pseudoscalar(ambient_dim, dim=None, dofdesc=None)[source]¶
Same as the outer product of all parametrization derivative columns.
- pytential.symbolic.primitives.normal(ambient_dim, dim=None, dofdesc=None)[source]¶
Exterior unit normals.
- pytential.symbolic.primitives.mean_curvature(ambient_dim, dim=None, dofdesc=None)[source]¶
(Numerical) mean curvature.
- pytential.symbolic.primitives.second_fundamental_form(ambient_dim, dim=None, dofdesc=None)[source]¶
Compute the second fundamental form of a surface. This is in reference to the reference-to-global mapping in use for each element.
Note
Some references assume that the second fundamental form is computed with respect to an orthonormal basis, which this is not.
- pytential.symbolic.primitives.expansion_radii(ambient_dim, dim=None, granularity=None, dofdesc=None)[source]¶
- pytential.symbolic.primitives.h_max(ambient_dim, dim=None, dofdesc=None)[source]¶
Defines a maximum element size in the discretization.
- pytential.symbolic.primitives.weights_and_area_elements(ambient_dim, dim=None, dofdesc=None)[source]¶
Combines
area_element()
andQWeight
.
Elementary numerics¶
- class pytential.symbolic.primitives.NumReferenceDerivative(ref_axes=None, operand=None, dofdesc=None)[source]¶
An operator that takes a derivative of operand with respect to the the element reference coordinates.
- class pytential.symbolic.primitives.NodeSum(operand=None)[source]¶
Implements a global sum over all discretization nodes.
- class pytential.symbolic.primitives.NodeMax(operand=None)[source]¶
Implements a global maximum over all discretization nodes.
- class pytential.symbolic.primitives.NodeMin(operand=None)[source]¶
Implements a global minimum over all discretization nodes.
- class pytential.symbolic.primitives.ElementwiseSum(operand=None, dofdesc=None)[source]¶
Returns a vector of DOFs with all entries on each element set to the sum of DOFs on that element.
- class pytential.symbolic.primitives.ElementwiseMax(operand=None, dofdesc=None)[source]¶
Returns a vector of DOFs with all entries on each element set to the maximum of DOFs on that element.
- pytential.symbolic.primitives.integral(ambient_dim, dim, operand, dofdesc=None)[source]¶
A volume integral of operand.
Operators¶
Geometric Calculus (based on Geometric/Clifford Algebra)¶
Conventional Calculus¶
- pytential.symbolic.primitives.dd_axis(axis, ambient_dim, operand)[source]¶
Return the derivative along (XYZ) axis axis (in ambient_dim-dimensional space) of operand.
- pytential.symbolic.primitives.d_dx()¶
- pytential.symbolic.primitives.d_dy()¶
- pytential.symbolic.primitives.d_dz()¶
- pytential.symbolic.primitives.grad_mv(ambient_dim, operand)[source]¶
Return the ambient_dim-dimensional gradient of operand as a
pymbolic.geometric_algebra.MultiVector
.
- pytential.symbolic.primitives.grad(ambient_dim, operand)[source]¶
Return the ambient_dim-dimensional gradient of operand as a
numpy.ndarray
.
Layer potentials¶
- class pytential.symbolic.primitives.IntG(target_kernel, source_kernels, densities, qbx_forced_limit, source=None, target=None, kernel_arguments=None, **kwargs)[source]¶
- \[\int_\Gamma T (\sum S_k G(x-y) \sigma_k(y)) dS_y\]
where \(\sigma_k\) is the k-th density, \(G\) is a Green’s function, \(S_k\) are source derivative operators and \(T\) is a target derivative operator.
- pytential.symbolic.primitives.int_g_dsource(ambient_dim, dsource, kernel, density, qbx_forced_limit, source=None, target=None, kernel_arguments=None, **kwargs)[source]¶
- \[\int_\Gamma \operatorname{dsource} \dot \nabla_y \dot g(x-y) \sigma(y) dS_y\]
where \(\sigma\) is density, and dsource, a multivector. Note that the first product in the integrand is a geometric product.
- pytential.symbolic.primitives.dsource¶
- pytential.symbolic.primitives.int_g_vec(kernel, density, qbx_forced_limit, source=None, target=None, kernel_arguments=None, **kwargs)[source]¶
Creates a vector of
IntG
objects from one kernel with source and target derivatives and maps a vector of densities into a vector ofIntG
objects.Historically
IntG
objects supported only one source kernel and allowed multiple densities to get a vector of objects as a convenience function. Now thatIntG
objects supports multiple source kernels with one density associated to each source kernel, the previous interface would lead to ambiguity. This function is intended to preserve the “vectorizing” behavior of of the constructor ofIntG
for use cases where that is preferred.
- pytential.symbolic.primitives.S(kernel, density, qbx_forced_limit=<class 'pytential.symbolic.primitives._unspecified'>, source=None, target=None, kernel_arguments=None, **kwargs)[source]¶
“Conventional” Vector Calculus¶
Pretty-printing expressions¶
Binding an operator to a discretization¶
- class pytential.GeometryCollection(places, auto_where=None)[source]¶
A mapping from symbolic identifiers (“place IDs”, typically strings) to ‘geometries’, where a geometry can be a
PotentialSource
, aTargetBase
or aDiscretization
.This class is meant to hold a specific combination of sources and targets serve to host caches of information derived from them, e.g. FMM trees of subsets of them, as well as related common subexpressions such as metric terms.
Refinement of
pytential.qbx.QBXLayerPotentialSource
entries is performed on demand, i.e. on calls toget_discretization()
with a specific discr_stage. To perform refinement explicitly, callpytential.qbx.refinement.refine_geometry_collection()
, which allows more customization of the refinement process through parameters.- __init__(places, auto_where=None)[source]¶
- Parameters
places – a scalar, tuple of or mapping of symbolic names to geometry objects. Supported objects are
PotentialSource
,TargetBase
andDiscretization
. If this is a mapping, the keys that are strings must be valid Python identifiers. The tuple should contain only two entries, denoting the source and target geometries for layer potential evaluation, identified by auto_where.auto_where – a single or a tuple of two
DOFDescriptor
s, or values that can be converted to one usingas_dofdesc()
. The two descriptors are used to define the default source and target geometries for layer potential evaluations. By default, they are set toDEFAULT_SOURCE
andDEFAULT_TARGET
for sources and targets, respectively.
- auto_source¶
Default
DOFDescriptor
for the source geometry.
- auto_target¶
Default
DOFDescriptor
for the target geometry.
- get_geometry(geometry)[source]¶
- Parameters
geometry – the identifier of the geometry in the collection.
- get_discretization(geometry, discr_stage=None)[source]¶
Get the geometry or discretization in the collection.
If a specific QBX stage discretization is requested, refinement is performed on demand and cached for subsequent calls.
- Parameters
geometry – the identifier of the geometry in the collection.
discr_stage – if the geometry is a
LayerPotentialSourceBase
, this denotes the QBX stage of the returned discretization. Can be one ofQBX_SOURCE_STAGE1
(default),QBX_SOURCE_STAGE2
orQBX_SOURCE_QUAD_STAGE2
.
- Returns
a geometry object in the collection or a
Discretization
corresponding to discr_stage.
- get_connection(from_dd, to_dd)[source]¶
Construct a connection from from_dd to to_dd geometries.
- Parameters
from_dd – a
DOFDescriptor
or a value that can be converted to one usingas_dofdesc()
.to_dd – as from_dd.
- Returns
an object compatible with the
DiscretizationConnection
interface.
- merge(places)[source]¶
Merges two geometry collections and returns the new collection.
- Parameters
places – a
dict
orGeometryCollection
to merge with the current collection. If it is empty, a copy of the current collection is returned.
- pytential.bind(places, expr, auto_where=None)[source]¶
- Parameters
places – a
pytential.GeometryCollection
. Alternatively, any list or mapping that is a valid argument for its constructor can also be used.auto_where – for simple source-to-self or source-to-target evaluations, find ‘where’ attributes automatically.
expr – one or multiple expressions consisting of primitives form
pytential.symbolic.primitives
(akapytential.sym
). Multiple expressions can be combined into one object to pass here in the form of anumpy
object array
- Returns
PDE operators¶
Scalar PDEs¶
- class pytential.symbolic.pde.scalar.L2WeightedPDEOperator(kernel: sumpy.kernel.Kernel, use_l2_weighting: bool)[source]¶
\(L^2\)-weighting for scalar IEs.
\(L^2\)-weighting is performed to help with the solution of IEs that yield locally singular densities. It does this by matching the \(\ell^2\)-norm used by the iterative method (e.g. GMRES) with the (approximate) \(L^2\)-norm. Clearly, singular densities might not have finite \(\ell^2\)-norm, hampering convergence of the iterative method. See Bremer, J. On the Nyström discretization of integral equations on planar curves with corners. ACHA, 2011..
- kernel¶
- use_l2_weighting¶
- get_weight(dofdesc=None)[source]¶
- Returns
a symbolic expression for the weights (quadrature weights and area elements) on dofdesc if
use_l2_weighting
is True and1
otherwise.
- get_sqrt_weight(dofdesc=None)[source]¶
- Returns
the square root of
get_weight()
.
- get_density_var(name: str)[source]¶
- Parameters
name – a string name for the density.
- Returns
a symbolic variable or array (problem dependent) corresponding to the density with the given name.
- prepare_rhs(b)[source]¶
Modify the right-hand side (e.g. boundary conditions) to match the operator constructed in
operator()
.
- representation(u, qbx_forced_limit=None, **kwargs)[source]¶
- Returns
a representation for the unknowns based on an integral equation with density u. If qbx_forced_limit denotes an on-surface evaluation, the corresponding jump relations are not added to the representation.
- operator(u, **kwargs)[source]¶
- Returns
a boundary integral operator with corresponding jump relations that can be used to solve for the density u.
- __init__(kernel: sumpy.kernel.Kernel, use_l2_weighting: bool)[source]¶
- class pytential.symbolic.pde.scalar.DirichletOperator(kernel: sumpy.kernel.Kernel, loc_sign: int, *, alpha: Optional[numbers.Number] = None, use_l2_weighting: bool = False, kernel_arguments: Optional[Dict[str, Any]] = None)[source]¶
IE operator and field representation for solving Dirichlet boundary value problems with scalar kernels (e.g.
LaplaceKernel
,HelmholtzKernel
,YukawaKernel
)Note
When testing this as a potential matcher, note that it can only access potentials that come from charge distributions having no net charge. (This is true at least in 2D)
Inherits from
L2WeightedPDEOperator
.- representation(u, map_potentials=None, qbx_forced_limit=None, **kwargs)[source]¶
- Parameters
u – symbolic variable for the density.
map_potentials – a callable that can be used to apply additional transformations on all the layer potentials in the representation, e.g. to take a target derivative.
kwargs – additional keyword arguments passed on to the layer potential constructor.
- operator(u, **kwargs)[source]¶
- Parameters
u – symbolic variable for the density.
kwargs – additional keyword arguments passed on to the layer potential constructor.
- __init__(kernel: sumpy.kernel.Kernel, loc_sign: int, *, alpha: Optional[numbers.Number] = None, use_l2_weighting: bool = False, kernel_arguments: Optional[Dict[str, Any]] = None)[source]¶
- Parameters
loc_sign – \(+1\) for exterior or \(-1\) for interior problems.
alpha – a complex coefficient with positive imaginary part for the combined-field integral representation (CFIE) for the Helmholtz equation (based on Brakhage and Werner). For other kernels, it does does not offer any benefits.
- class pytential.symbolic.pde.scalar.NeumannOperator(kernel: sumpy.kernel.Kernel, loc_sign: int, *, alpha: Optional[numbers.Number] = None, use_improved_operator: bool = True, use_l2_weighting: bool = False, kernel_arguments: Optional[Dict[str, Any]] = None)[source]¶
IE operator and field representation for solving Neumann boundary value problems with scalar kernels (e.g.
LaplaceKernel
,HelmholtzKernel
,YukawaKernel
)Note
When testing this as a potential matcher, note that it can only access potentials that come from charge distributions having no net charge. (This is true at least in 2D)
Inherits from
L2WeightedPDEOperator
.- representation(u, map_potentials=None, qbx_forced_limit=None, **kwargs)[source]¶
- Parameters
u – symbolic variable for the density.
map_potentials – a callable that can be used to apply additional transformations on all the layer potentials in the representation, e.g. to take a target derivative.
- operator(u, **kwargs)[source]¶
- Parameters
u – symbolic variable for the density.
kwargs – additional keyword arguments passed on to the layer potential constructor.
- __init__(kernel: sumpy.kernel.Kernel, loc_sign: int, *, alpha: Optional[numbers.Number] = None, use_improved_operator: bool = True, use_l2_weighting: bool = False, kernel_arguments: Optional[Dict[str, Any]] = None)[source]¶
- Parameters
loc_sign – \(+1\) for exterior or \(-1\) for interior problems.
alpha – a complex coefficient with positive imaginary part for the combined-field integral representation (CFIE) for the Helmholtz equation (based on Brakhage and Werner). For other kernels, it does does not offer any benefits.
use_improved_operator – if True use the least singular operator available. Only used when alpha is not \(0\).
- class pytential.symbolic.pde.scalar.BiharmonicClampedPlateOperator(kernel: sumpy.kernel.Kernel, loc_sign: int)[source]¶
IE operator and field representation for solving clamped plate Biharmonic equation where,
\[\begin{split}\begin{cases} \Delta^2 u = 0, & \quad \text{ on } D, \\ u = g_1, & \quad \text{ on } \partial D, \\ \mathbf{n} \cdot \nabla u = g_2, & \quad \text{ on } \partial D. \end{cases}\end{split}\]This operator assumes that the boundary data \((g_1, g_2)\) are represented as column vectors and vertically stacked. For details on the formulation see Problem C in [Farkas1990].
Note
This operator supports only interior problem.
- Farkas1990(1,2)
Farkas, Peter, Mathematical foundations for fast algorithms for the biharmonic equation, Technical Report 765, Department of Computer Science, Yale University, 1990, PDF.
- representation(sigma, map_potentials=None, qbx_forced_limit=None, **kwargs)[source]¶
- Parameters
sigma – symbolic variable for the density.
map_potentials – a callable that can be used to apply additional transformations on all the layer potentials in the representation, e.g. to take a target derivative.
kwargs – additional keyword arguments passed on to the layer potential constructor.
- operator(sigma, **kwargs)[source]¶
- Parameters
u – symbolic variable for the density.
kwargs – additional keyword arguments passed on to the layer potential constructor.
- Returns
the second kind integral operator for the clamped plate problem from [Farkas1990].
- __init__(kernel: sumpy.kernel.Kernel, loc_sign: int)[source]¶
- Parameters
loc_sign – \(+1\) for exterior or \(-1\) for interior problems.
Maxwell’s equations¶
- pytential.symbolic.pde.maxwell.get_sym_maxwell_point_source(kernel, jxyz, k)[source]¶
Return a symbolic expression that, when bound to a
pytential.source.PointPotentialSource
will yield a field satisfying Maxwell’s equations.Uses the sign convention \(\exp(-i \omega t)\) for the time dependency.
This will return an object of six entries, the first three of which represent the electric, and the second three of which represent the magnetic field. This satisfies the time-domain Maxwell’s equations as verified by
sumpy.point_calculus.frequency_domain_maxwell()
.
- pytential.symbolic.pde.maxwell.get_sym_maxwell_plane_wave(amplitude_vec, v, omega, epsilon=1, mu=1, dofdesc=None)[source]¶
Return a symbolic expression that, when bound to a
pytential.source.PointPotentialSource
will yield a field satisfying Maxwell’s equations.- Parameters
amplitude_vec – should be orthogonal to v. If it is not, it will be orthogonalized.
v – a three-vector representing the phase velocity of the wave (may be an object array of variables or a vector of concrete numbers) While v may mathematically be complex-valued, this function is for now only tested for real values.
omega – Accepts the “Helmholtz k” to be compatible with other parts of this module.
Uses the sign convention \(\exp(-1 \omega t)\) for the time dependency.
This will return an object of six entries, the first three of which represent the electric, and the second three of which represent the magnetic field. This satisfies the time-domain Maxwell’s equations as verified by
sumpy.point_calculus.frequency_domain_maxwell()
.
- class pytential.symbolic.pde.maxwell.PECChargeCurrentMFIEOperator(k=None)[source]¶
Magnetic Field Integral Equation operator with PEC boundary conditions, under the assumption of no surface charges.
See
contrib/notes/mfie.tm
in the repository for a derivation.The arguments loc below decide between the exterior and the interior MFIE. The “exterior” (loc=1) MFIE enforces a zero field on the interior of the integration surface, whereas the “interior” MFIE (loc=-1) enforces a zero field on the exterior.
Uses the sign convention \(\exp(-1 \omega t)\) for the time dependency.
for the sinusoidal time dependency.
- scattered_volume_field(Jt, rho, qbx_forced_limit=None)[source]¶
This will return an object array of six entries, the first three of which represent the electric, and the second three of which represent the magnetic field. This satisfies the time-domain Maxwell’s equations as verified by
sumpy.point_calculus.frequency_domain_maxwell()
.
Stokes’ equations¶
- class pytential.symbolic.stokes.StokesletWrapper(dim=None)[source]¶
Wrapper class for the
StokesletKernel
kernel.This class is meant to shield the user from the messiness of writing out every term in the expansion of the double-indexed Stokeslet kernel applied to the density vector. The object is created to do some of the set-up and bookkeeping once, rather than every time we want to create a symbolic expression based on the kernel – say, once when we solve for the density, and once when we want a symbolic representation for the solution, for example.
The
apply()
function returns the integral expressions needed for the vector velocity resulting from convolution with the vector density, and is meant to work similarly to callingS()
(which isIntG
).Similar functions are available for other useful things related to the flow:
apply_pressure()
,apply_derivative()
(target derivative),apply_stress()
(applies symmetric viscous stress tensor in the requested direction).- kernel_dict¶
The dictionary allows us to exploit symmetry – that \(S_{01}\) is identical to \(S_{10}\) – and avoid creating multiple expansions for the same kernel in a different ordering.
- apply(density_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic expressions for integrating Stokeslet kernel.
Returns an object array of symbolic expressions for the vector resulting from integrating the dyadic Stokeslet kernel with variable density_vec_sym.
- Parameters
density_vec_sym – a symbolic vector variable for the density vector.
mu_sym – a symbolic variable for the viscosity.
qbx_forced_limit – the qbx_forced_limit argument to be passed on to
IntG
.
- apply_pressure(density_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic expression for pressure field associated with the Stokeslet.
- apply_derivative(deriv_dir, density_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic derivative of velocity from Stokeslet.
Returns an object array of symbolic expressions for the vector resulting from integrating the deriv_dir target derivative of the dyadic Stokeslet kernel with variable density_vec_sym.
- Parameters
deriv_dir – integer denoting the axis direction for the derivative.
density_vec_sym – a symbolic vector variable for the density vector.
mu_sym – a symbolic variable for the viscosity.
qbx_forced_limit – the qbx_forced_limit argument to be passed on to
IntG
.
- apply_stress(density_vec_sym, dir_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic expression for viscous stress applied to a direction.
Returns a vector of symbolic expressions for the force resulting from the viscous stress
\[-p \delta_{ij} + \mu (\nabla_i u_j + \nabla_j u_i)\]applied in the direction of dir_vec_sym.
Note that this computation is very similar to computing a double-layer potential with the Stresslet kernel in
StressletWrapper
. The difference is that here the direction vector is applied at the target points, while in the Stresslet the direction is applied at the source points.- Parameters
density_vec_sym – a symbolic vector variable for the density vector.
dir_vec_sym – a symbolic vector for the application direction.
mu_sym – a symbolic variable for the viscosity.
qbx_forced_limit – the qbx_forced_limit argument to be passed on to
IntG
.
- class pytential.symbolic.stokes.StressletWrapper(dim=None)[source]¶
Wrapper class for the
StressletKernel
kernel.This class is meant to shield the user from the messiness of writing out every term in the expansion of the triple-indexed Stresslet kernel applied to both a normal vector and the density vector. The object is created to do some of the set-up and bookkeeping once, rather than every time we want to create a symbolic expression based on the kernel – say, once when we solve for the density, and once when we want a symbolic representation for the solution, for example.
The
apply()
function returns the integral expressions needed for convolving the kernel with a vector density, and is meant to work similarly toS()
(which isIntG
).Similar functions are available for other useful things related to the flow:
apply_pressure()
,apply_derivative()
(target derivative),apply_stress()
(applies symmetric viscous stress tensor in the requested direction).- kernel_dict¶
The dictionary allows us to exploit symmetry – that \(T_{012}\) is identical to \(T_{120}\) – and avoid creating multiple expansions for the same kernel in a different ordering.
- apply(density_vec_sym, dir_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic expressions for integrating Stresslet kernel.
Returns an object array of symbolic expressions for the vector resulting from integrating the dyadic Stresslet kernel with variable density_vec_sym and source direction vectors dir_vec_sym.
- Parameters
density_vec_sym – a symbolic vector variable for the density vector.
dir_vec_sym – a symbolic vector variable for the direction vector.
mu_sym – a symbolic variable for the viscosity.
qbx_forced_limit – the qbx_forced_limit argument to be passed on to
IntG
.
- apply_pressure(density_vec_sym, dir_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic expression for pressure field associated with the Stresslet.
- apply_derivative(deriv_dir, density_vec_sym, dir_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic derivative of velocity from stresslet.
Returns an object array of symbolic expressions for the vector resulting from integrating the deriv_dir target derivative of the dyadic Stresslet kernel with variable density_vec_sym and source direction vectors dir_vec_sym.
- Parameters
deriv_dir – integer denoting the axis direction for the derivative.
density_vec_sym – a symbolic vector variable for the density vector.
dir_vec_sym – a symbolic vector variable for the normal direction.
mu_sym – a symbolic variable for the viscosity.
qbx_forced_limit – the qbx_forced_limit argument to be passed on to
IntG
.
- apply_stress(density_vec_sym, normal_vec_sym, dir_vec_sym, mu_sym, qbx_forced_limit)[source]¶
Symbolic expression for viscous stress applied to a direction.
Returns a vector of symbolic expressions for the force resulting from the viscous stress
\[-p \delta_{ij} + \mu (\nabla_i u_j + \nabla_j u_i)\]applied in the direction of dir_vec_sym.
- Parameters
density_vec_sym – a symbolic vector variable for the density vector.
normal_vec_sym – a symbolic vector variable for the normal vectors (outward facing normals at source locations).
dir_vec_sym – a symbolic vector for the application direction.
mu_sym – a symbolic variable for the viscosity.
qbx_forced_limit – the qbx_forced_limit argument to be passed on to
IntG
.
- class pytential.symbolic.stokes.StokesOperator(ambient_dim, side)[source]¶
- ambient_dim¶
- side¶
- __init__(ambient_dim, side)[source]¶
- Parameters
ambient_dim – dimension of the ambient space.
side – \(+1\) for exterior or \(-1\) for interior.
- prepare_rhs(b, *, mu)[source]¶
- Returns
a (potentially) modified right-hand side b that matches requirements of the representation.
- operator(sigma)[source]¶
- Returns
the integral operator that should be solved to obtain the density sigma.
- class pytential.symbolic.stokes.HsiaoKressExteriorStokesOperator(*, omega, alpha=None, eta=None)[source]¶
Representation for 2D Stokes Flow based on [HsiaoKress1985].
Inherits from
StokesOperator
.- HsiaoKress1985(1,2)
G. C. Hsiao and R. Kress, On an Integral Equation for the Two-Dimensional Exterior Stokes Problem, Applied Numerical Mathematics, Vol. 1, 1985, DOI.
- __init__(*, omega, alpha=None, eta=None)[source]¶
- Parameters
omega – farfield behaviour of the velocity field, as defined by \(A\) in [HsiaoKress1985] Equation 2.3.
alpha – real parameter \(\alpha > 0\).
eta – real parameter \(\eta > 0\). Choosing this parameter well can have a non-trivial effect on the conditioning.
- class pytential.symbolic.stokes.HebekerExteriorStokesOperator(*, eta=None)[source]¶
Representation for 3D Stokes Flow based on [Hebeker1986].
Inherits from
StokesOperator
.- Hebeker1986
F. C. Hebeker, Efficient Boundary Element Methods for Three-Dimensional Exterior Viscous Flow, Numerical Methods for Partial Differential Equations, Vol. 2, 1986, DOI.
Internal affairs¶
Mappers¶
How a symbolic operator gets executed¶
- class pytential.symbolic.execution.BoundExpression(places, sym_op_expr)[source]¶
An expression readied for evaluation by binding it to a
GeometryCollection
.- cost_per_stage(calibration_params, **kwargs)[source]¶
- Parameters
queue – a
pyopencl.CommandQueue
object.calibration_params – either a
dict
returned by estimate_kernel_specific_calibration_params, or astr
“constant_one”.
- Returns
a
dict
mapping from instruction to per-stage cost. Each per-stage cost is represented by adict
mapping from the stage name to the predicted time.
- cost_per_box(calibration_params, **kwargs)[source]¶
- Parameters
queue – a
pyopencl.CommandQueue
object.calibration_params – either a
dict
returned by estimate_kernel_specific_calibration_params, or astr
“constant_one”.
- Returns
a
dict
mapping from instruction to per-box cost. Each per-box cost is represented by anumpy.ndarray
orpyopencl.array.Array
of shape (nboxes,), where the ith entry represents the cost of all stages for box i.
- scipy_op(actx: arraycontext.impl.pyopencl.PyOpenCLArrayContext, arg_name, dtype, domains=None, **extra_args)[source]¶
- Parameters
domains – a list of discretization identifiers or None values indicating the domains on which each component of the solution vector lives. None values indicate that the component is a scalar. If domains is None,
DEFAULT_TARGET
is required to be a key inplaces
.- Returns
An object that (mostly) satisfies the
scipy.sparse.linalg.LinearOperator
protocol, except for accepting and returningpyopencl.array.Array
arrays.
- eval(context=None, timing_data=None, array_context: Optional[arraycontext.impl.pyopencl.PyOpenCLArrayContext] = None)[source]¶
Evaluate the expression in self, using the
pyopencl.CommandQueue
queue and the input variables given in the dictionary context.- Parameters
timing_data – A dictionary into which timing data will be inserted during evaluation. (experimental)
array_context – only needs to be supplied if no instances of
DOFArray
with aPyOpenCLArrayContext
are supplied as part of context.
- Returns
the value of the expression, as a scalar,
pyopencl.array.Array
, or an object array of these.
- __call__(*args, **kwargs)[source]¶
Evaluate the expression in self, using the
pyopencl.CommandQueue
queue and the input variables given in the dictionary context.- Returns
the value of the expression, as a scalar,
meshmode.dof_array.DOFArray
, or an object array of these.
- places¶
Created by calling
pytential.bind()
.