FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
marenv::wake::WakeField Class Referenceabstract

#include <WakeField.h>

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

Public Member Functions

virtual Status Sample (double t, const double pos[3], WakeSample &out) const =0
 
virtual WakeSampleParts SampleParts (double t, const double pos[3]) const
 
virtual bool MayReach (const WakeQueryRegion &region) const
 

Detailed Description

Models the effect of objects (net panels, structures, vessels) on the surrounding flow field.

A wake field is defined in the frame of its source. At a query point it returns a velocity deficit d in [0, 1] and the source velocity u_s (WakeSample). The waked velocity is u = u_amb + d (u_s - u_amb): d = 0 leaves the ambient flow undisturbed and d = 1 moves the water with the source. The velocity ratio of the KF2012 and MF2022 screen models is r = 1 - d. Because the deficit acts on the velocity relative to the source, a source towed through still water drags water along at d u_s, and a source drifting with the current casts no wake (Galilean invariance).

The field carries its own orientation (the relative-flow direction at the source), so the query takes no current direction.

When several wake fields are registered in marenv::EnvironmentFacade, their deficits compose by the momentum-flux rule, d_tot (1 - d_tot) = sum d_i (1 - d_i) (owner ruling R95, MomentumFluxSum in Superposition.h), and the combined source velocity is the deficit-weighted mean of the u_s,i. The wake acts on the current only, not on the wave particle velocity.

Example usage:

auto wake = std::make_shared<SimpleWake>();
env.AddWakeField("cage_wake", wake);
double pos[3] = {0.0, 0.0, 5.0};
env.GetWakedFlow(0.0, pos, flow); // flow.waked = flow.ambient + flow.deficit * (u_s - flow.ambient)
Definition EnvironmentFacade.h:42
Definition EnvironmentFacade.h:27

Member Function Documentation

◆ MayReach()

virtual bool marenv::wake::WakeField::MayReach ( const WakeQueryRegion &  region) const
inlinevirtual

Returns false only if the field, as published now, contributes nothing in a region (owner decision R47).

Parameters
[in]regionThe sphere and time interval of the queries, and the cutoff.
Returns
False only if Sample(t, pos) gives d = 0 (region.cutoff = 0) or d < region.cutoff (region.cutoff > 0), or a status other than OK, for every pos in the sphere and every t in [region.tBegin, region.tEnd]; true otherwise, or when the field cannot tell.

A blending field counts the snapshot it blends to from the publish instant on, though its weight is 0 there, so the answer also covers SampleParts() taken in the interval and composed at a later time (R136). The answer holds for the state published at the call; a later Publish() voids it. The default returns true, so a field without a reach test is never culled. SourceSetWake implements it. Const and thread-safe, as Sample().

Reimplemented in marenv::wake::SourceSetWake.

◆ Sample()

virtual Status marenv::wake::WakeField::Sample ( double  t,
const double  pos[3],
WakeSample &  out 
) const
pure virtual

Returns the wake deficit and source velocity at a given position and time (contract C4).

Parameters
[in]tSimulation time, s.
[in]posPosition (x,y,z) to query, m, NED.
[out]outDeficit in [0, 1] and source velocity at pos.
Returns
marenv::Status::OK on success; Status::ERROR_NOT_SET, which means d = 0, before the first Publish() and, for a field with an extent (GriddedWake), outside it. The direct field (SourceSetWake, after its first blend has started) has no extent and returns OK with d = 0 far from its sources (MENV-0014). See marenv::Status for other values.

Threading contract, for every implementation:

  • Registration (EnvironmentFacade::AddWakeField, RemoveWakeField) happens during setup only; the facade's registry is not synchronised.
  • After registration, one writer thread may update the field (Publish()) concurrently with any number of reader threads calling Sample().
  • Sample() is const and thread-safe. It reads one immutable snapshot, so a query that runs during an update returns the old or the new state, never a mix. It takes no mutex.

Known caveat: the snapshot fields hold their snapshot in std::atomic<std::shared_ptr<const ...>>, as marenv::wave::LinearWaveTheory does. libstdc++ implements it with a spin bit in the control pointer (is_lock_free() is false), held while load() or store() updates the reference count, so a query can spin briefly against another thread's load or store. Test W8 (tests/WakeThreading_Test.cpp) checks the contract under the MARENV_TSAN build.

Implemented in marenv::wake::GriddedWake, marenv::wake::SourceSetWake, and environment::NetCageWakeField.

◆ SampleParts()

virtual WakeSampleParts marenv::wake::WakeField::SampleParts ( double  t,
const double  pos[3] 
) const
inlinevirtual

Returns the sample at a position and time split into the parts its blend weighs, to compose at a later time (owner ruling R136; contract C4).

Parameters
[in]tSample time, s.
[in]posPosition (x,y,z) to query, m, NED.
Returns
The parts; WakeSampleParts::At(t2) for t2 >= t gives the deficit and source velocity of the snapshots at (t, pos) with the blend weight of t2. Where the field does not blend at t or later, At(t2) is Sample(t, pos) bit for bit for every t2.

The default holds Sample(t, pos), for a field without a blend. SourceSetWake and GriddedWake return the samples of the snapshot blended to and of the state blended from while they blend. Const and thread-safe, as Sample(); it reads one snapshot of the published state.

Reimplemented in marenv::wake::GriddedWake, and marenv::wake::SourceSetWake.


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