Source code for zefir.potential.flows.superposition
"""
Potential superposition implementation.
This module provides the PotentialSuperposition class for combining multiple
potential flows into a single composite flow field.
"""
import numpy as np
from ...typing import CplxNDArray, List, ParamType
from .base import ComplexPotential
from zefir.logging import debug, info, error
[docs]
class PotentialSuperposition(ComplexPotential):
"""Superposition of multiple potential flows.
This class allows combining multiple potential flows into a single flow field
by linear superposition. Since the potential flow equations are linear, the
sum of valid potential flows is also a valid potential flow.
Parameters
----------
flows : List[ComplexPotential], optional
List of flow objects to superpose (default: empty list)
Attributes
----------
_flows : List[ComplexPotential]
List of constituent flows
Methods
-------
append(flow)
Add a flow to the superposition
Examples
--------
>>> from zefir.potential import UniformFlow, SourceFlow, DoubletFlow
>>> # Create a flow around a cylinder (uniform + doublet)
>>> flow = PotentialSuperposition()
>>> flow.append(UniformFlow((1.0, 0.0)))
>>> flow.append(DoubletFlow(1.0, (0.0, 0.0)))
>>> z = np.array([2+0j, 0+2j, -2+0j])
>>> potential = flow(z)
>>> velocity = flow.velocity(z)
"""
[docs]
def __init__(self, flows: List[ComplexPotential]|None=None):
self._flows = flows if flows is not None else []
debug(f"Created PotentialSuperposition with {len(self._flows)} flows")
[docs]
def append(self, flow:ComplexPotential):
"""Add a flow to the superposition.
Parameters
----------
flow : ComplexPotential
Flow object to add to the superposition
Examples
--------
>>> superposition = PotentialSuperposition()
>>> superposition.append(UniformFlow((1.0, 0.0)))
"""
flow_name = flow.__class__.__name__
debug(f"Appending {flow_name} to superposition (now {len(self._flows)+1} flows)")
self._flows.append(flow)
[docs]
def __call__(self, z: CplxNDArray, deriv:int=0) -> CplxNDArray:
"""Evaluate the complex potential or its derivative.
Parameters
----------
z : CplxNDArray
Complex array of points where the potential is evaluated
deriv : int, optional
Derivative level: 0 for potential, 1 for velocity
Returns
-------
CplxNDArray
Sum of potentials/velocities from all flows
"""
debug(f"Evaluating superposition of {len(self._flows)} flows at {z.size} points (deriv={deriv})")
out = np.zeros(z.shape, dtype=z.dtype)
for i, flow in enumerate(self._flows):
out += flow(z, deriv=deriv)
return out