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 SampleExcluding (double t, const double pos[3], std::span< const int > excludedTags, WakeSample &out) const override
 
WakeSampleParts SamplePartsExcluding (double t, const double pos[3], std::span< const int > excludedTags) const override
 SampleParts() with the sources of the given tags left out in every snapshot, as SampleExcluding() (ENV-0107).
 
- Public Member Functions inherited from marenv::wake::BlendedField< detail::SourceSetSnapshot >
Status Sample (double t, const double pos[3], Value &out) const override
 
Traits::Parts SampleParts (double t, const double pos[3]) const override
 
bool MayReach (const WakeQueryRegion &region) const override
 
std::uint64_t Revision () const override
 The number of publishes (see WakeField::Revision()).
 
bool StaticFrom (double t) const override
 No blend at t or later and the published snapshot at rest (see WakeField::StaticFrom()).
 
void SampleMany (double t, std::span< const std::array< double, 3 > > positions, std::span< Value > out, std::span< Status > status) const override
 Sample() at every point, the published state loaded once (see WakeField::SampleMany()).
 
void Sketch (double t, FieldSketch &out) const override
 Appends the sketch of the snapshot blended to at t (see WakeField::Sketch()); nothing before the first publish.
 

Additional Inherited Members

- Public Types inherited from marenv::wake::BlendedField< detail::SourceSetSnapshot >
using Value = typename Traits::Value
 The sample type of the field, Traits::Value.
 
- Protected Types inherited from marenv::wake::BlendedField< detail::SourceSetSnapshot >
using Blend = WakeBlend< detail::SourceSetSnapshot, Value, typename Traits::Sum, typename Traits::Samples >
 The blend between the two published snapshots (WakeBlend).
 
- Protected Member Functions inherited from marenv::wake::BlendedField< detail::SourceSetSnapshot >
Status SampleWith (double t, const double pos[3], const Sampler &sampler, Value &out) const
 
Traits::Parts PartsWith (double t, const double pos[3], const Sampler &sampler) const
 SampleParts() with each snapshot sampled by sampler, as SampleWith().
 
- Protected Attributes inherited from marenv::wake::BlendedField< detail::SourceSetSnapshot >
Blend m_blend
 The published snapshots and the blend between them (single writer).
 

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.

Reach (MayReach(), 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 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().

The virtuals that only load the state and forward to the snapshot (Sample(), SampleParts(), MayReach(), Revision(), StaticFrom(), SampleMany(), Sketch()) are those of BlendedField. Sample() returns Status::OK where a published source set contributes and Status::ERROR_NOT_SET, with d = 0, before the first Publish() and before the first blend has started. Revision() is the number of publishes; StaticFrom(t) holds with no blend at t or later and the published sources at rest; Sketch() appends the point and line sources of the set blended to at t.

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

◆ 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.

◆ SampleExcluding()

Status marenv::wake::SourceSetWake::SampleExcluding ( double  t,
const double  pos[3],
std::span< const int >  excludedTags,
WakeSample &  out 
) const
override

Returns the blended sample with the sources of the given tags left out, source and images (see WakeField::SampleExcluding; ENV-0107).

A point source whose ElementarySource::tag is in excludedTags contributes nothing, in every snapshot of the blend; line sources carry no tag and always contribute. With no tag to leave out it is Sample() bit for bit. The cost of a query grows by one search of the tags per point source.


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