Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYChemin9613Solver2024.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012-2024> <EDF-DTG> <FRANCE>
3  * This file is part of Code_TYMPAN (R).
4  * Code_TYMPAN (R) is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * Code_TYMPAN (R) is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  * You should have received a copy of the GNU General Public License along
13  * with Code_TYMPAN (R). If not, see <https://www.gnu.org/licenses/>.
14  */
15 
17 
19  const OSpectreOctave& Agr_r,
20  const OSpectreOctave& Agr_m, double hs,
21  double hr, double dp) const
22 {
23  OSpectreOctave Agr9613 = TYChemin9613Solver::calcTotalGroundAttenuation(Agr_s, Agr_r, Agr_m, hs, hr, dp);
24  double Kgeo = (dp * dp + (hs - hr) * (hs - hr)) / (dp * dp + (hs + hr) * (hs + hr));
25  OSpectreOctave s = Agr9613 * (-1.0);
26  s = s.div(10.0);
27  s = s.exp(std::log(10));
28  s = (s + (-1.0)) * Kgeo + 1.0;
29  s = s.log() * (-10.0);
30 
31  return s;
32 }
33 
35  const OPoint3D& S, const OPoint3D& O, const OPoint3D& R, double a, double h, const OVector3D& n) const
36 {
37  // first we need to set a convention to the normal of the surface:
38  // (1) it is a normal of a vertical plane (vertical component = 0)
39  // (2) it is normalized
40  // (3) from O, it points towards S and R
41  OVector3D nCopy{n}; // a copy is necessary because coordinates cannot be retrieved for a const OVector3D
42  const double nx = nCopy.getCoords()[0];
43  const double ny = nCopy.getCoords()[1];
44  OVector3D nConventional{nx, ny, 0.}; // condition (1)
45  nConventional.normalize(); // condition (2)
46  const OVector3D OSvec{O, S};
47  if (OSvec.scalar(nConventional) < 0.) // condition (3)
48  {
49  nConventional.invert();
50  }
51 
52  // to compute cos(beta_a) and cos(beta_h), we need to perform 2D geometry in two planes:
53  // - a horizontal plane passing by O --> cos(beta_a)
54  // - a vertical plane passing by O --> cos(beta_h)
55  // for that, we define normalized tangential vectors of the reflecting surface
56  // - tHorizontal
57  // - tVertical
58  const OVector3D tVertical{0., 0., 1.};
59  OVector3D tHorizontal = tVertical.cross(nConventional);
60  tHorizontal.normalize();
61 
62  // cos(beta_a)
63  const double OSvecHorizontalT = OSvec.scalar(tHorizontal);
64  const double OSvecN = OSvec.scalar(nConventional);
65  const OVector3D OSvecHorizontal = tHorizontal * OSvecHorizontalT + nConventional * OSvecN;
66  const double dSOHorizontal = OSvecHorizontal.norme();
67  const double cos_beta_a = OSvecN / dSOHorizontal;
68 
69  // cos(beta_h)
70  const double OSvecVerticalT = OSvec.scalar(tVertical);
71  const OVector3D OSvecVertical = tVertical * OSvecVerticalT + nConventional * OSvecN;
72  const double dSOVertical = OSvecVertical.norme();
73  const double cos_beta_h = OSvecN / dSOVertical;
74 
75  // l_eff (Eq. 27)
76  const double l_eff = std::min(a * cos_beta_a, h * cos_beta_h);
77 
78  // distances
79  const double d_SO = OSvec.norme();
80  const OVector3D ORvec{O, R};
81  const double d_OR = ORvec.norme();
82 
83  // f_threshold (Eq. 26 multiplied by c)
84  const double c_9613_2 = 340.0; // TODO: to factorize by using somehow the constant defined in
85  // TYAcousticModel::computeWaveLength
86  const double fThreshold = c_9613_2 * (2. / (l_eff * l_eff)) * (d_SO * d_OR) / (d_SO + d_OR);
87 
88  // filter spectrum
89  OSpectreOctave filter{0.};
91  for (unsigned int i = 0; i < frequencies.size(); i++)
92  {
93  if (frequencies[i] > fThreshold)
94  {
95  filter.getTabValReel()[i] = 1.;
96  }
97  }
98 
99  return filter;
100 }
NxReal s
Definition: NxVec3.cpp:317
#define min(a, b)
Representation of one of the most optimal path between source and receptor: S—>R Specific derivation ...
void getCoords(double coords[3])
Gets the coordinates as an array of double.
Definition: 3d.cpp:90
The 3D point class.
Definition: 3d.h:487
static OTabFreq getTabFreqExact()
Definition: spectre.cpp:1590
The 3D vector class.
Definition: 3d.h:298
double norme() const
Computes the length of this vector.
Definition: 3d.cpp:215
void normalize()
Normalizes this vector.
Definition: 3d.cpp:225
OVector3D cross(const OVector3D &vector) const
Cross product.
Definition: 3d.cpp:196
OSpectreOctave calcTotalGroundAttenuation(const OSpectreOctave &Agr_s, const OSpectreOctave &Agr_r, const OSpectreOctave &Agr_m, double hs, double hr, double dp) const override
Compute total ground attenuation Agr from region ground attenuations and geometric configuration.
OSpectreOctave calcMinimalExtensionConditionOneReflection(const OPoint3D &S, const OPoint3D &O, const OPoint3D &R, double a, double h, const OVector3D &n) const override
Evaluate minimal extension condition for a specular reflection on a flat surface in function of the w...
virtual OSpectreOctave calcTotalGroundAttenuation(const OSpectreOctave &Agr_s, const OSpectreOctave &Agr_r, const OSpectreOctave &Agr_m, double hs, double hr, double dp) const
Compute total ground attenuation Agr from region ground attenuations and geometric configuration.
std::vector< double > OTabFreq
Frequencies collection.
Definition: spectre.h:60