Wavefront propagator for the WaveQ3D model.
Implemented using a third order Adams-Bashforth algorithm which estimates the new position and direction from the previous three iterations.
where:
The actual work of computing these derivatives and the effects of the ocean environment is done by the wave_front class. The wave_front entries are stored in a circular queue so that environmental parameters computations and wavefront derivatives can be reused by subsequent time steps.
enum spreading_type |
wave_queue | ( | ocean_model & | ocean, | |
const seq_vector & | freq, | |||
const wposition1 & | pos, | |||
const seq_vector & | de, | |||
const seq_vector & | az, | |||
double | time_step, | |||
const wposition * | targets = NULL , |
|||
const size_t | run_id = 1 , |
|||
spreading_type | type = HYBRID_GAUSSIAN | |||
) |
Initialize a propagation scenario.
ocean | Reference to the environmental parameters. | |
freq | Frequencies over which to compute propagation (Hz). | |
pos | Location of the wavefront source in spherical earth coordinates. | |
de | Initial depression/elevation angles at the source location (degrees, positive is up). Requires a minimum of 3 angles if eigenrays are being computed. | |
az | Initial azimuthal angle at the source location (degrees, clockwise from true north). Requires a minimum of 3 angles if eigenrays are being computed. Ray fans that wrap around all azimuths should include rays for both 0 and 360 degrees. | |
time_step | Propagation step size (seconds). | |
targets | List of acoustic targets. | |
run_id | Run Identification number. | |
type | Type of spreading model to use: CLASSIC_RAY or HYBRID_GAUSSIAN. |
~wave_queue | ( | ) | [virtual] |
Destroy all temporary memory.
bool addEigenrayListener | ( | eigenrayListener * | pListener | ) |
Add a eigenrayListener to the _eigenrayListenerVec vector.
void build_eigenray | ( | size_t | t1, | |
size_t | t2, | |||
size_t | de, | |||
size_t | az, | |||
double | distance2[3][3][3] | |||
) | [protected] |
Used by detect_eigenrays() to compute eigneray parameters and add a new eigenray entry to the current target.
Used by detect_eigenrays() to compute eigenray parameters and add a new eigenray entry to the current target.
Uses compute_offset() to find offsets in time, source D/E, and source AZ that minimize the distance to the target. This routine uses these offsets and a Taylor series for direction to compute the target D/E and AZ.
Intensity is computed using either a classic ray theory or a hybrid Gaussian beam summation across the wavefront. Attenuation is incorporated into the ray intensity using an interpolation in time along the CPA ray. Phase is copied from the CPA as are the counts for surface, bottom, and caustics.
t1 | Row number of the current target. | |
t2 | Column number of the current target. | |
de | D/E angle index number. Can not equal a value at the edge of the ray fan. | |
az | AZ angle index number. Can not equal a value at the edge of the ray fan. | |
distance2 | Distance squared to each of the 27 neighboring points. The first index is time, the second is D/E and the third is AZ. Warning: this array is modified during the computation. |
bool checkEigenrayListeners | ( | long | waveTime | ) |
For each eigenrayListener in the _eigenrayListenerVec vector call the checkEigenrays method to deliver all eigenrays after a certain amount of time has passed.
waveTime | Current Time of the WaveFront in msec |
void close_netcdf | ( | ) |
Close netCDF wavefront log.
void collision_location | ( | size_t | de, | |
size_t | az, | |||
double | dtime, | |||
wposition1 * | position, | |||
wvector1 * | ndirection, | |||
double * | speed | |||
) | const [protected] |
Computes a refined location and direction at the point of collision.
Compute the precise location and direction at the point of collision.
Uses a second order Taylor series around the current location to estimate these values.
de | D/E angle index number. | |
az | AZ angle index number. | |
dtime | The distance (in time) from the "current" wavefront to the collision. | |
position | Refined position of the collision (output). | |
ndirection | Normalized direction at the point of collision (output). | |
speed | Speed of sound at the point of collision (output). |
void compute_offsets | ( | size_t | t1, | |
size_t | t2, | |||
size_t | de, | |||
size_t | az, | |||
const double | distance2[3][3][3], | |||
const c_vector< double, 3 > & | delta, | |||
c_vector< double, 3 > & | offset, | |||
c_vector< double, 3 > & | distance | |||
) | [protected] |
Find relative offsets and true distances in time, D/E, and AZ.
Find relative offsets and true distances in time, D/E, and azimuth.
Uses the analytic solution for the inverse of a symmetric 3x3 matrix to solve
H x = g x = inv(H) g
where
If the determinant of the 3x3 matrix is very small, the inverse is unstable, and this implementation falls back to a 2x2 calculation in the time and AZ directions. If the determinant of the 2x2 matrix is also very small, This implementation falls back to a solution that just uses the diagonal of the Hessian.
x(n) = - g(n) / H(n,n)
This fallback solution is limited to 1/2 of the beamwidth. If this clipping is not performed, the eigenray_extra_test/eigenray_lloyds will generate significant errors in D/E. But including this clipping leads to large D/E errors when the target is outside of the ray fan, like it is in the Bottom Bounce path for eigenray_test/eigenray_basic.
Computes distances from offsets, for each coordinate, by assuming that the other two offsets are zero.
d(n)^2 = - g(n) x(n) - 0.5*H(n,n) x(n)^2
If this Taylor series around the CPA is unstable, this implementation reverts to a simpler calculation that limits the inverse to the time and AZ directions. The neighborhood is treated as unstable if:
If the neighborhood is unstable, the distance in the DE direction is computed by subtracting the time and AZ distance from the total distances at CPA.
d(DE)^2 = d(total)^2 - d(time)^2 - d(AZ)^2
t1 | Row number of the current target. | |
t2 | Column number of the current target. | |
de | D/E angle index number. Can not equal a value at the edge of the ray fan. | |
az | AZ angle index number. Can not equal a value at the edge of the ray fan. | |
distance2 | Distance squared to each of the 27 neighboring points. The first index is time, the second is D/E and the third is AZ. | |
delta | Axis step size in each dimension. The first index is time, the second is D/E and the third is AZ. | |
offset | Distance to the current target in ray coordinate units. The first index is time offset, the second is launch angle D/E offset, and the third is launch angle AZ offset. Maximum limited to +/- 1 beam. (output) | |
distance | Distance to the current target in world coordinate units (meters). Give the distance the same sign as the relative offset. (output) |
const wave_front* curr | ( | ) | const [inline] |
Return const current element in the wavefront.
const wave_front* curr | ( | ) | [inline] |
Return current element in the wavefront.
void detect_caustics | ( | size_t | de, | |
size_t | az | |||
) | [protected] |
Detects and processes all of the logic necessary to determine points along the wavefronts that have folded over and mark them as caustics.
Detects and processes the caustics along the next wavefront.
This logic determines if any two points have crossed over each other when going from current wavefront to the next.
void detect_eigenrays | ( | ) | [protected] |
Detect and process wavefront closest point of approach (CPA) with target.
Requires a minimum of three rays in the D/E and AZ directions. Targets beyond the edge of the wavefront are matched to the next ray inside the fan.
void detect_reflections | ( | ) | [protected, virtual] |
Detect and process boundary reflections and caustics.
Loops through all of the "next" wavefront elements to see if any are on the wrong side of a boundary.
Relies on detect_reflections_surface() and detect_reflections_bottom() to do the actual work of detecting and processing reflections. These routines work recursively with their opposite so that multiple reflections can take place in a single time step. This is critical in very shallow water where the reflected position may already be beyond the opposing boundary.
At the end of this process, the wave_front::find_edges() routine is used to break the wavefront down into ray families. A ray family is defined by a set of rays that have the same surface, bottom, or caustic count.
bool detect_reflections_bottom | ( | size_t | de, | |
size_t | az | |||
) | [protected] |
Detect and process reflection for a single (DE,AZ) combination.
The attenuation and phase of reflection loss are added to the values currently being stored in the next wave element. Works recursively with detect_reflections_surface() so that multiple reflections can take place in a single time step.
de | D/E angle index number. | |
az | AZ angle index number. |
bool detect_reflections_surface | ( | size_t | de, | |
size_t | az | |||
) | [protected] |
Detect and process surface reflection for a single (DE,AZ) combination.
Detect and process reflection for a single (DE,AZ) combination.
The attenuation and phase of reflection loss are added to the values currently being stored in the next wave element. Works recursively with detect_reflections_bottom() so that multiple reflections can take place in a single time step.
de | D/E angle index number. | |
az | AZ angle index number. |
void detect_vertices | ( | size_t | de, | |
size_t | az | |||
) | [protected] |
Upper and lower vertices are present when the wavefront undergoes a change in direction in the water column but does not interact with the surface or bottom.
Detects upper and lower vertices along the wavefront.
A lower vertex is present if this point on the wavefront is a local minimum in time. Conversely, an upper vertex is present if it is a local maximum in time.
const seq_vector* frequencies | ( | ) | const [inline] |
List of frequencies for this wave queue.
const size_t getID | ( | ) | [inline] |
Get the type of wavefront that this is, i.e.
a wavefront originating from a source or receiver. This is exclusively used within the reverbation models.
double getIntensityThreshold | ( | ) | [inline] |
getIntensityThreshold
void init_netcdf | ( | const char * | filename, | |
const char * | long_name = NULL | |||
) |
Initialize recording to netCDF wavefront log.
Opens the file and records initial conditions. The file structure is illustrated by the netCDF sample below:
netcdf sample_test { dimensions: frequency = 1 ; source_de = 25 ; source_az = 9 ; travel_time = UNLIMITED ; // (### currently) variables: double frequency(frequency) ; frequency:units = "hertz" ; double source_de(source_de) ; source_de:units = "degrees" ; source_de:positive = "up" ; double source_az(source_az) ; source_az:units = "degrees_true" ; source_az:positive = "clockwise" ; double travel_time(travel_time) ; travel_time:units = "seconds" ; double latitude(travel_time, source_de, source_az) ; latitude:units = "degrees_north" ; double longitude(travel_time, source_de, source_az) ; longitude:units = "degrees_east" ; double altitude(travel_time, source_de, source_az) ; altitude:units = "meters" ; altitude:positive = "up" ; short surface(travel_time, source_de, source_az) ; surface:units = "count" ; short bottom(travel_time, source_de, source_az) ; bottom:units = "count" ; short caustic(travel_time, source_de, source_az) ; caustic:units = "count" ; short upper_vertex(travel_time, source_de, source_az) ; caustic:units = "count" ; short lower_vertex(travel_time, source_de, source_az) ; caustic:units = "count" ; byte on_edge(travel_time, source_de, source_az) ; caustic:units = "bool" ;
// global attributes: :Conventions = "COARDS" ;
data: frequency = 2000 ; source_de = 0, 1, 2, ... source_az = -1, 0, 1 ; travel_time = 0, 0.1, 0.2, ... latitude = 45, 45, 45, ... longitude = -45, -45, -45, ... altitude = -75, -75, -75, ... etc... }
filename | Name of the file to write to disk. | |
long_name | Optional global attribute for identifying data-set. |
void init_wavefronts | ( | ) | [protected] |
Initialize wavefronts at the start of propagation using a 3rd order Runge-Kutta algorithm.
The Runge-Kutta algorithm is much more computationally expensive than the Adams-Bashforth algorithm used during propagation. But Runge-Kutta is self starting, only happens at initialization, and it avoids introducing the start-up errors that would be present with cheaper methods.
Assumes that all of the elements of the _curr wavefront have been initialized prior to this initialization. When this method is complete, the wavefront elements for _past, _prev, _and _next will all have valid position, direction, and closest point of approach data. However, the _next element will not have been checked for interface collisions or eigenray collisions with targets.
bool is_closest_ray | ( | size_t | t1, | |
size_t | t2, | |||
size_t | de, | |||
size_t | az, | |||
const double & | center, | |||
double | distance2[3][3][3] | |||
) | [protected] |
Used by detect_eigenrays() to discover if the current ray is the closest point of approach (CPA) to the current target.
Used by detect_eigenrays() to discover if the current ray is the closest point of approach to the current target.
Computes the distance to each of the 27 neighboring wavefront points for later use in the calculation of eigenray interpolation products.
Exits early if the central ray is on the edge of a ray family. Exits early if the distance to any of the surrounding points is smaller than the distance to the central point, unless that point is on the edge of the ray family, to which the search continues. Ties are awarded to the higher time, higher D/E, and higher AZ. Extrapolates outside of ray families by not testing to see if points on the edge of the family are closer to the target than the central ray.
Assumes that the wavefront has three rays in the D/E and AZ directions. Also assumes that the calling routine does not search the rays on the edges of the wavefront. This ensures that each of the tested rays has valid rays to either side of it.
t1 | Row number of the current target. | |
t2 | Column number of the current target. | |
de | D/E angle index number. | |
az | AZ angle index number. | |
center | Reference to the center of the distance2 cube. | |
distance2 | Distance squared to each of the 27 neighboring points. The first index is time, the second is D/E and the third is AZ (output). |
virtual bool is_ray_valid | ( | size_t | de, | |
size_t | az | |||
) | [inline, virtual] |
Protoype of the function that is needed during reflections and only implemented in reverberation wave_queues.
void make_taylor_coeff | ( | const double | value[3][3][3], | |
const c_vector< double, 3 > & | delta, | |||
double & | center, | |||
c_vector< double, 3 > & | gradient, | |||
c_matrix< double, 3, 3 > & | hessian | |||
) | [static, protected] |
Computes the Taylor series coefficients used to compute eigenrays.
Computes the Taylor coefficients used to compute eigenrays.
The vector Taylor series uses the first derivative (gradient) and second derivative (Hessian) to estimate eigenray products as a function of time, D/E, and AZ from the closest point of approach (CPA).
value | Value to interpolate around the CPA. | |
delta | Axis step size in each dimension. The first index is time, the second is D/E and the third is AZ. | |
center | Value at the center of the grid (output). | |
gradient | First derivative in 3 dimensions (output). | |
hessian | Second derivative in 3 dimensions (output). |
const wave_front* next | ( | ) | const [inline] |
Return const next element in the wavefront.
const wave_front* next | ( | ) | [inline] |
Return next element in the wavefront.
bool notifyEigenrayListeners | ( | size_t | targetRow, | |
size_t | targetCol, | |||
eigenray | pEigenray | |||
) | [protected] |
For each eigenrayListener in the _eigenrayListenerVec vector call the addEigenray method to provide eigenrays to object that requested them.
For each eigenrayListener in the _eigenrayListenerVec vector call the addEigenray method to provide eigenrays.
size_t num_az | ( | ) | const [inline] |
Number of AZ angles in the ray fan.
size_t num_de | ( | ) | const [inline] |
Number of D/E angles in the ray fan.
const wave_front* past | ( | ) | const [inline] |
Return const past element in the wavefront.
const wave_front* past | ( | ) | [inline] |
Return past element in the wavefront.
const wave_front* prev | ( | ) | const [inline] |
Return const previous element in the wavefront.
const wave_front* prev | ( | ) | [inline] |
Return previous element in the wavefront.
bool removeEigenrayListener | ( | eigenrayListener * | pListener | ) |
Remove a eigenrayListener from the _eigenrayListenerVec vector.
void save_netcdf | ( | ) |
Write current record to netCDF wavefront log.
Records travel time, latitude, longtiude, altitude for the current wavefront.
void setID | ( | size_t | id | ) | [inline] |
Set the type of wavefront that this is, i.e.
a wavefront originating from a source or receiver. This is exclusively used within the reverbation models.
void setIntensityThreshold | ( | double | dThreshold | ) | [inline] |
setIntensityThreshold
dThreshold | The new value of the intensity threshold in dB. |
double source_az | ( | size_t | az | ) | const [inline] |
Initial azimuthal angle at the source location.
az | Index of the element to access. |
double source_de | ( | size_t | de | ) | const [inline] |
Initial depression/elevation angle at the source location.
de | Index of the element to access. |
const wposition1& source_pos | ( | ) | const [inline] |
Location of the wavefront source in spherical earth coordinates.
void step | ( | ) |
Marches to the next integration step in the acoustic propagation.
Uses the third order Adams-Bashforth algorithm to estimate the position and direction of each point on the next wavefront from the previous three iterations. Automatically rotates the queue and updates the environmental parameters on the new wavefront.
Accumulated non-spreading losses are computed by combining the individual values in the next wavefront with prior losses in the current wavefront.
If targets have been specified, this function calls detect_eigenrays() at the end of each step to search for wavefront collisions with those targets.
At the end of each step, the next iteration may extend beyond one of the boundaries. This allows the eigenray calculation to accurately portray targets near the interface. Reflections are computed at the beginning of the next iteration to ensure that the next wave elements are alway inside of the water column.
const wposition* targets | ( | ) | const [inline] |
List of acoustic targets.
double time | ( | ) | const [inline] |
Elapsed time for the current element in the wavefront.
double time_step | ( | ) | const [inline] |
Propagation step size (seconds).
friend class reflection_model [friend] |
friend class spreading_hybrid_gaussian [friend] |
friend class spreading_ray [friend] |
bool _az_boundary [protected] |
Create an Azimuthal boundary loop condition upon initialization.
This condition will prevent the production of multiple eigenrays for instances where the first azimuthal angle is equivalent to the last azimuthal angle in the AZ vector that is passed.
wave_front * _curr [protected] |
bool _de_branch [protected] |
Treat all targets that are slightly away from directly above the source as special cases.
std::vector<eigenrayListener *> _eigenrayListenerVec [protected] |
Vector containing the references of objects that will be used to update classes that require eigenrays as they are built.
These classes must implement addEigenray method.
const seq_vector* _frequencies [protected] |
Frequencies over which to compute propagation loss (Hz).
Defined as a pointer to support virtual methods in seq_vector class.
double _intensity_threshold [protected] |
The value of the intensity threshold in dB Any eigenray intensity values that are weaker than this threshold are not sent the proplossListner(s); Defaults to -300 dB.
NcVar * _nc_altitude [private] |
NcVar * _nc_bottom [private] |
NcVar * _nc_caustic [private] |
NcFile* _nc_file [private] |
The netCDF file used to record the wavefront log.
Reset to NULL when not initialized.
NcVar * _nc_latitude [private] |
NcVar * _nc_longitude [private] |
NcVar * _nc_lower [private] |
NcVar * _nc_on_edge [private] |
long _nc_rec [private] |
Current record number in netDCF file.
NcVar * _nc_surface [private] |
NcVar* _nc_time [private] |
The netCDF variables used to record the wavefront log.
NcVar * _nc_upper [private] |
wave_front * _next [protected] |
ocean_model& _ocean [protected] |
Reference to the environmental parameters.
Assumes that the storage for this data is managed by calling routine.
wave_front* _past [protected] |
Circular queue of wavefront elements needed by the third order Adams-Bashforth algorithm.
wave_front * _prev [protected] |
reflection_model* _reflection_model [protected] |
Reference to the reflection model component.
size_t _run_id [protected] |
Run Identification.
const seq_vector* _source_az [protected] |
Initial azimuthal angle (AZ) at the source location (degrees, clockwise from true north).
Defined as a pointer to support virtual methods in seq_vector class.
const seq_vector* _source_de [protected] |
Initial depression/elevation angle (D/E) at the source location (degrees, positive is up).
Defined as a pointer to support virtual methods in seq_vector class.
wposition1 _source_pos [protected] |
Location of the wavefront source in spherical earth coordinates.
Adjusted during construction of the wave_queue if it is within 0.1 meters of being above the ocean surface or below the ocean bottom. The boundary reflection logic does not perform correctly if the wavefront starts on the wrong side of either boundary.
spreading_model* _spreading_model [protected] |
Reference to the spreading loss model component.
Supports either classic ray theory or Hybrid Gaussian Beams.
matrix<double> _targets_sin_theta [protected] |
Intermediate term: sin of colatitude for targets.
By caching this value here, we avoid re-calculating it each time the that wave_front::compute_target_distance() needs to compute the distance squared from each target to each point on the wavefront.
double _time [protected] |
Time for current entry in the wave_front circular queue (seconds).
double _time_step [protected] |
Propagation step size (seconds).