capytaine.tools.perturbation_expansion module

Truncated perturbation series (“higher-order dual numbers”).

class capytaine.tools.perturbation_expansion.DifferenceFrequencyExpansion(coefficients)[source]

Bases: PerturbationExpansion

Order-2 expansion of a field in a sea made of several wave components at one frequency.

For a field of shape S, with W wave components (e.g. wave directions):

  • order 0, shape S: still water value (geometry, hydrostatic pressure, …). Must be real.

  • order 1, shape (W, *S): x1[m] is the complex amplitude of the response to wave m alone.

  • order 2, shape (W, W, *S): x2[m, n] is the difference-frequency QTF: the second-order part of the field is sum_mn x2[m, n] exp(-i (omega_m - omega_n) t). Hermitian in (m, n).

Products keep the difference-frequency part of the product of first-order terms: Q_mn = 1/4 (a_m conj(b_n) + conj(a_n) b_m), such that Q_mm = 1/2 Re(a_m conj(b_m)) is the mean value. A complex factor (e.g. i*omega) must be applied to the first-order amplitudes before building the expansion, never to an expansion that has an order-2 part.

The order-0 and order-2 coefficients can be given as scalars (e.g. 0), and are then broadcast. When two operands have a different number of field axes, size-1 axes are inserted in front of the field axes of the one that has fewer (NumPy broadcasting of the field axes only). The wave axes are leading batch axes and the field axes are at the end: index with x[…, i].

constant(value, order=2)[source]

Embed value as the order-0 term, zero elsewhere (stored as broadcast views).

evaluate(eps)[source]

Numerically sum the series at a concrete eps (mainly for validation/testing).

property field_ndim
classmethod first_order(amplitudes)[source]

First-order quantity: zero order 0 and order 2, and amplitudes of shape (W, *S) as order 1.

property nb_waves
class capytaine.tools.perturbation_expansion.PerturbationExpansion(coefficients)[source]

Bases: object

A quantity x0 + eps*x1 + eps^2*x2 + … + eps^N*xN, truncated at order N.

Each coefficient may be a plain scalar or a numpy array (vector, matrix, …). Use .coefficients[k] to get the raw coefficient of a specific order. Two expansions can only be combined if they share the same truncation order N. Plain scalars and arrays used as operands are constants: x stands for x + 0*eps + ….

The axes of the “field” (e.g. (nb_faces, 3) for a vector field) are at the end of the coefficients. Leading axes are batch axes, such as the wave axes of DifferenceFrequencyExpansion. Operations act on each coefficient with the usual NumPy broadcasting rules. Methods taking an axis (sum, expand_dims, squeeze) take a negative axis (axis=-1 for the last one), and trace and T act on the last two axes.

property T
classmethod constant(value, order)[source]

Embed value as the order-0 term of an order-order expansion, zero elsewhere.

det()[source]

Matrix determinant. Expansion of det(I + A) = 1 + tr(A) + 1/2 (tr(A)^2 - tr(A @ A)) + …, up to order 2.

evaluate(eps)[source]

Numerically sum the series at a concrete eps (mainly for validation/testing).

expand_dims(axis)[source]

Insert a field axis of size 1 at position axis (negative).

inv()[source]

Matrix inverse. Expansion of (I + A)^-1 = I - A + A @ A - …, up to order 2.

squeeze(axis)[source]

Remove the field axis of size 1 at position axis (negative).

sum(axis)[source]

Sum over the field axis (or tuple of axes) axis (negative).

trace()[source]

Trace over the last two field axes.

transpose()[source]

Swap the last two field axes.