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