38 return (option ? 1.0 + value: value);
48 return (option ? sqrt(2.0 + value) * sqrt(0.0 - value) : sqrt(1.0 + value) * sqrt(1.0 - value));
80 JBellhop_t(
const sin_t& s,
105 static constexpr double STEP_SIZE_M = 0.001;
106 static constexpr size_t NUMBER_OF_ITERATIONS = 1000;
115 JBellhop(
const JAbstractSoundVelocity& V,
const double precision) :
130 sin_t operator()(
const double x0,
133 const double z1)
const
137 const double st = fabs(x1 - x0) / hypot(x1 - x0, z1 - z0);
139 double st_min = (z1 > z0 ? st : 0.0);
140 double st_max = (z1 > z0 ? 1.0 : st);
142 if (fabs(x1 - x0) > fabs(z1 - z0)) {
147 for (
size_t i = 0; i != NUMBER_OF_ITERATIONS; ++i) {
149 double s0 = 0.5*(st_min + st_max);
155 while ((x - x1) * copysign(1.0, x1 - x0) < -0.5 * STEP_SIZE_M) {
157 const double c = sqrt(2.0 + s) * sqrt(-s);
158 const double dx = copysign(STEP_SIZE_M, x1 - x0);
159 const double dz = copysign(STEP_SIZE_M * c / (1.0 + s), z1 - z0);
161 s += (1.0 + s) * (V(z + dz) - V(z)) / V(z + 0.5*dz);
169 }
else if (s <= -1.0) {
171 z = numeric_limits<double>::max();
177 if (fabs(z - z1) <= precision) {
181 if ((z - z1) * copysign(1.0, z1 - z0) > 0.0)
189 for (
size_t i = 0; i != NUMBER_OF_ITERATIONS; ++i) {
191 double s0 = 0.5*(st_min + st_max);
197 while ((z - z1) * copysign(1.0, z1 - z0) < -0.5 * STEP_SIZE_M) {
199 const double c = sqrt((1.0 + s) * (1.0 - s));
200 const double dx = copysign(STEP_SIZE_M * s / c, x1 - x0);
201 const double dz = copysign(STEP_SIZE_M, z1 - z0);
203 s += s * (V(z + dz) - V(z)) / V(z + 0.5*dz);
209 x = numeric_limits<double>::max();
213 }
else if (s < 0.0) {
219 if (fabs(x - x1) <= precision) {
220 return {
false, s0 };
223 if ((x - x1) * copysign(1.0, x1 - x0) < 0.0)
230 THROW(JException,
"Reached maximum number of iterations " << NUMBER_OF_ITERATIONS);
244 JBellhop_t operator()(
const sin_t& s0,
248 const double z1)
const
260 while ((x - x1) * copysign(1.0, x1 - x0) < -0.5 * STEP_SIZE_M) {
262 const double c = sqrt(2.0 + s) * sqrt(-s);
263 const double dx = copysign(STEP_SIZE_M, x1 - x0);
264 const double dz = copysign(STEP_SIZE_M * c / (1.0 + s), z1 - z0);
265 const double v = V(z + 0.5*dz);
267 s += (1.0 + s) * (V(z + dz) - V(z)) / v;
270 d += sqrt(dx*dx + dz*dz);
271 t += sqrt(dx*dx + dz*dz) / v;
281 while ((z - z1) * copysign(1.0, z1 - z0) < -0.5 * STEP_SIZE_M) {
283 const double c = sqrt((1.0 + s) * (1.0 - s));
284 const double dx = copysign(STEP_SIZE_M * s / c, x1 - x0);
285 const double dz = copysign(STEP_SIZE_M, z1 - z0);
286 const double v = V(z + 0.5*dz);
288 s += s * (V(z + dz) - V(z)) / v;
291 d += sqrt(dx*dx + dz*dz);
292 t += sqrt(dx*dx + dz*dz) / v;
301 return JBellhop_t({s0.option,s},
x, z, t, d);
305 const JAbstractSoundVelocity& V;
329 JParser<> zap(
"Example program for sound ray tracing.");
338 catch(
const exception &error) {
345 const JBellhop
bellhop(V, precision);
360 cout <<
"> " << flush;
361 cin >> x0 >> z0 >> x1 >>
z1;
366 const double D =
hypot(x1 - x0,
z1 - z0);
368 const JBellhop_t result =
bellhop(
s0, x0, z0, x1,
z1);
381 const double v0 = V(z0);
382 const double v1 = V(
z1);
383 const double b = (
v1 -
v0) / (
z1 - z0);
384 const double c =
v1 /
v0;
385 const double u = (
v0 +
v1) /
v1;
386 const double v = (
v0 -
v1) /
v1;
387 const double st =
s0.value;
396 dx = (sqrt(2.0 +
st) * sqrt(0.0 -
st) - sqrt(1.0 + c + c *
st) * sqrt(1.0 - c - c *
st)) *
v0 / (1.0 +
st) / b;
400 dx = (sqrt(1.0 +
st) * sqrt(1.0 -
st) - sqrt(1.0 + c *
st) * sqrt(1.0 - c *
st)) *
v0 / (
st ) / b;
405 const double x =
s0.getc();
406 const double y = (
s0.option ? c * sqrt(
u +
st) * sqrt(v -
st) : sqrt(1.0 + c *
st) * sqrt(1.0 - c *
st));
410 catch(
const exception& error) {
417 const double x0 = 0.0;
418 const double z0 = 0.0;
425 TH2D h2(
"h2",
NULL, 50, 1.0, 3.5, 50, -1.0, 3.0);
430 const double x1 = pow(10.0, h2.GetXaxis()->GetBinCenter(
ix));
431 const double z1 = pow(10.0, h2.GetYaxis()->GetBinCenter(
iy));
438 const double D =
hypot(x1 - x0,
z1 - z0);
440 const JBellhop_t result =
bellhop(
s0, x0, z0, x1,
z1);
442 Qx.
put(result.x - x1);
443 Qz.put(result.z -
z1);
445 h2.SetBinContent(
ix,
iy, (result.t - V.
getTime(D, z0,
z1)) * 1.0e6);
447 catch(
const exception& error) {
int main(int argc, char **argv)
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
General purpose messaging.
#define DEBUG(A)
Message macros.
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Template definition of a multi-dimensional oscillation probability interpolation table.
Utility class to parse command line options.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Interface for depth dependend velocity of sound.
Implementation for depth dependend velocity of sound.
virtual double getTime(const double D_m, const double z1, const double z2) const override
Get propagation time of sound.
JSoundVelocity & set(const double z0)
Set depth.
Auxiliary base class for aritmetic operations of derived class types.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Auxiliary data structure for floating point format specification.