FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
marenv::wake::SourceSetWake Class Reference

#include <SourceSetWake.h>

+ Inheritance diagram for marenv::wake::SourceSetWake:
+ Collaboration diagram for marenv::wake::SourceSetWake:

Public Member Functions

 SourceSetWake ()=default
 A field whose sources compose with the default KernelParams.
 
 SourceSetWake (const KernelParams &params)
 
void Publish (SourceSet sources, const double velocity[3], double t0, double blendTime, double seabedDepth)
 
Status Sample (double t, const double pos[3], WakeSample &out) const override
 
bool MayReach (const WakeQueryRegion &region) const override
 
WakeSampleParts SampleParts (double t, const double pos[3]) const override
 

Detailed Description

Wake field of point and line sources by direct evaluation, cross-faded from one published source set to the next (contract C4).

The field of a wake-casting object's lumped source, of a net's private field in the Direct evaluation, of a fixed analytic source (fhsim_environment's PorousDiscWakeSource) and the reference against which a gridded wake is judged. Sample() evaluates ElementaryDeficit() of every point source and LineDeficit() of every line source at the query point and composes them by params.superposition (lead ruling R88, owner ruling R95): Product, deficit = 1 - prod(1 - d_i) (the default; a net's private field), or MomentumFlux, deficit (1 - deficit) = sum d_i (1 - d_i) (MomentumFluxSum; the lumped fields, LumpedKernel()). Each source has the images of MirrorImages(params): a mirror image at the free surface and one at the seabed (owner ruling R53) and, with both planes, the image of each at the other plane (R98). An image's deficit at pos is the source's deficit at the image's query depth of pos, composed in by the same rule. The cost of a query is O(N) kernel evaluations per source and image (up to 5 per source); each source's KernelProfile is built once per publish (MENV-0036).

One Publish(SourceSet, velocity, t0, blendTime, seabedDepth) moves the sources with velocity (a source given at p is at p + velocity (t - t0) at time t), drags the water at velocity (u_s) and starts the blend at t0, so a wake cannot travel at one velocity and drag the water at another; the seabed depth of the images (R53) is per publish. A source fixed in space is published with velocity 0.

Blending (WakeBlend): the field cross-fades from the source set in use to the new one over blendTime from t0, with the C1 smoothstep s = 3 tau^2 - 2 tau^3, tau = (t - t0) / blendTime. The weights act on the waked velocity: d = (1 - s) d_old + s d_new, and d u_s is blended the same way; the source velocity is d u_s / d, or zero where d = 0. The first source set fades in from no wake (outside the field before t0); a blend time of 0 replaces the set in use at once, for every t. Publish() refuses a new blend while the previous one is still running (lead ruling R22, WakeBlend::Publish()), so a state blends from the previous source set alone and no blend chain forms.

Thread safety (see WakeField::Sample): register the field during setup only. After that one writer thread may call Publish() concurrently with readers; Sample() is const and thread-safe. Publish() builds a new immutable blend state, which holds the source sets' snapshots directly, and swaps it in through std::atomic<std::shared_ptr<const ...>>, the pattern of GriddedWake, so a query does one atomic load (MENV-0025) and a query running concurrently with Publish() evaluates either the old or the new state, never a mix. Keep to one writer. Sample() takes no mutex; the libstdc++ spin bit of the atomic shared pointer is the known caveat.

Constructor & Destructor Documentation

◆ SourceSetWake()

marenv::wake::SourceSetWake::SourceSetWake ( const KernelParams &  params)
explicit

A field whose sources compose with the kernel params (MENV-0058).

Parameters
[in]paramsKernel parameters of every Publish(); its seabedDepth is not used: every Publish() gives its own.

Member Function Documentation

◆ MayReach()

bool marenv::wake::SourceSetWake::MayReach ( const WakeQueryRegion &  region) const
overridevirtual

Returns false only if the published state contributes nothing in the region (see WakeField::MayReach).

A source set may reach the region unless, at the exact tier (region.cutoff = 0), the whole sphere, swept back by the sources' translation over the interval, lies upstream of x_start of every source, where the kernel is 0; or, at the cutoff tier, the sum over the sources of a bound of the kernel over that sphere (the largest centreline amplitude over its x range times the Gaussian at its smallest distance from the axis and the largest sigma) is below region.cutoff; the composed deficit is at most that sum (MomentumFluxBound() of it for MomentumFlux). The images (R53, R98) are bounded the same way, as their sources over the region moved to each image's query depth. The blended deficit is at most the larger of the two source sets' deficits, so the field may reach the region when a source set it samples in [region.tBegin, region.tEnd] or later may: the set blended to from its publish instant on (owner ruling R136, for held SampleParts()), the set blended from until the blend has ended by tBegin. True before the first Publish().

Reimplemented from marenv::wake::WakeField.

◆ Publish()

void marenv::wake::SourceSetWake::Publish ( SourceSet  sources,
const double  velocity[3],
double  t0,
double  blendTime,
double  seabedDepth 
)

Publishes a source set, blended in from the one in use (MENV-0058).

Parameters
[in]sourcesThe point and line sources, world NED at t0; each flowDir (and axis) is normalised. An empty set gives a zero deficit.
[in]velocityVelocity of the sources, m/s, NED: they translate with it from t0 on and drag the water at it (u_s).
[in]t0Time at which the sources are at their given positions and the blend starts, s.
[in]blendTimeDuration of the cross-fade, s; 0 switches at once.
[in]seabedDepthDepth of the seabed image plane (R53), m; infinity: no seabed image. It replaces KernelParams::seabedDepth of the constructor's params for this publish, so every caller gives it (there is no default: a params.seabedDepth would be lost silently).
Exceptions
std::logic_errorif the previous blend has not ended by t0 (R22, WakeBlend::Publish()).
std::invalid_argumentfor a negative blend time, a non-finite t0 or velocity, a seabed depth for which Validate() throws, a point source with a non-finite position, area or momentum deficit, a non-positive area, a negative momentum deficit or a zero flowDir (MENV-0047, MENV-0049), or a line source with a non-finite or non-positive length or width, a negative momentum deficit, a zero flowDir or axis, or an axis parallel to flowDir (LineKernelProfile, MENV-0044). A throwing Publish() leaves the field in use unchanged.

◆ Sample()

Status marenv::wake::SourceSetWake::Sample ( double  t,
const double  pos[3],
WakeSample &  out 
) const
overridevirtual

Returns the blended deficit and source velocity at pos (see WakeField::Sample).

Parameters
[in]tSimulation time, s.
[in]posPosition (x,y,z) to query, m, NED.
[out]outDeficit in [0, 1] and deficit-weighted source velocity.
Returns
Status::OK where a published source set contributes; Status::ERROR_NOT_SET before the first Publish() and before the first blend has started, with d = 0.

Implements marenv::wake::WakeField.

◆ SampleParts()

WakeSampleParts marenv::wake::SourceSetWake::SampleParts ( double  t,
const double  pos[3] 
) const
overridevirtual

Returns the sample split into the parts the blend weighs (see WakeField::SampleParts; owner ruling R136).

While the published state blends at t or later, the parts hold the sample of the set blended to and of the set blended from at (t, pos); otherwise Sample(t, pos).

Reimplemented from marenv::wake::WakeField.


The documentation for this class was generated from the following file: