Code_TYMPAN  4.4.0
Industrial site acoustic simulation
entities.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 
24 #include <vector>
25 #include <numeric>
26 #include "entities.hpp"
27 
28 #include <math.h>
30 
31 namespace tympan
32 {
33 AcousticMaterialBase::AcousticMaterialBase(const string& name_) : name(name_) {}
34 
35 // ---------
37 
39  : AcousticMaterialBase(name_), spectrum(spectrum_)
40 {
41 }
42 
44 {
45  ComplexSpectrum eyring(spectrum);
46  // 1-e^(-alphaS)
47  return (ComplexSpectrum)eyring.exp(-1.0).mult(-1.0).sum(1.0);
48 }
49 
50 // ---------
51 AcousticGroundMaterial::AcousticGroundMaterial(const string& name_, double resistivity_, double deviation_,
52  double length_, double factor_g_)
53  : AcousticMaterialBase(name_), resistivity(resistivity_), thickness(1.0), deviation(deviation_),
54  length(length_), factor_g(factor_g_)
55 {
56  init();
57 }
58 
60 {
61  computeZc();
62  computeK();
63 }
64 
65 bool AcousticGroundMaterial::compare(const string& name, double resistivity, double deviation, double length,
66  double factor_g)
67 {
68  // If same name and characteristics
69  // return true
70  return ((this->name == name) && (this->resistivity == resistivity) && (this->deviation == deviation) &&
71  (this->length == length) && (this->factor_g == factor_g));
72 }
73 
74 ComplexSpectrum AcousticGroundMaterial::get_absorption(double incidence_angle, double length)
75 {
76  ComplexSpectrum Zs, Rp, W, Fw, Q;
77  computeZs(incidence_angle, Zc, Zs);
78  computeZf(incidence_angle, Zs);
79  computeRp(incidence_angle, Zf, Rp);
80  computeW(incidence_angle, length, Zf, W);
81  computeFw(W, Fw);
82  computeQ(incidence_angle, Rp, Fw, Q);
83 
84  Q = Q.toModulePhase();
86 
87  return Q;
88 }
89 
91 {
92  return factor_g;
93 }
94 
96 {
97  double sigmaSurF = NAN;
98  OTabFreq tabFreq = OSpectre::getTabFreqExact(); // On travaille en frequence reelle
99 
100  for (unsigned int i = 0; i < Zc.getNbValues(); i++)
101  {
102  sigmaSurF = resistivity / tabFreq[i];
103 
104  Zc.getTabValReel()[i] = 1.0 + 9.08 * pow(sigmaSurF, 0.75);
105  Zc.getTabValImag()[i] = 11.9 * pow(sigmaSurF, 0.73);
106  }
107 
109 }
110 
112 {
113  double k_value = NAN, FSurSigma = NAN;
114 
115  OTabFreq tabFreq = OSpectre::getTabFreqExact(); // On travaille en frequence reelle
116 
117  for (unsigned int i = 0; i < K.getNbValues(); i++)
118  {
119  FSurSigma = tabFreq[i] / resistivity;
120 
121  k_value = atmosphere->get_k().getTabValReel()[i];
122 
123  K.getTabValReel()[i] = k_value * (1 + 10.8 * pow(FSurSigma, -0.7));
124  K.getTabValImag()[i] = k_value * (10.3 * pow(FSurSigma, -0.59));
125  }
126 
127  K.setType(SPECTRE_TYPE_AUTRE);
128 }
129 
131 {
132  double k_value = NAN;
133 
134  TYComplex operand, K_value, Z_value;
135  double cosPhi = cos(angle);
136 
137  TYComplex cplxVal;
138 
139  for (unsigned int i = 0; i < Z.getNbValues(); i++)
140  {
141  k_value = atmosphere->get_k().getTabValReel()[i];
142  K_value = TYComplex(K.getTabValReel()[i], K.getTabValImag()[i]);
143  Z_value = TYComplex(Z.getTabValReel()[i], Z.getTabValImag()[i]);
144 
145  operand = std::sqrt(CPLX_UN - ((k_value * cosPhi / K_value) * (k_value * cosPhi / K_value)));
146 
147  cplxVal = Z_value * cotanh(CPLX_MUN * CPLX_J * K_value * thickness * operand) / operand;
148  spectrum.getTabValReel()[i] = cplxVal.real();
149  spectrum.getTabValImag()[i] = cplxVal.imag();
150  }
151 }
152 
154 {
155  double k0_value = NAN, k_value = NAN, intv_a = NAN, intv_b = NAN;
156  size_t size = Zf.getNbValues();
157  ComplexSpectrum Bf;
158 
159  for (unsigned int i = 0; i < size; i++)
160  {
161  k0_value = atmosphere->get_k().getTabValReel()[i];
162  k_value = k0_value * sin(angle);
163 
164  // Partie réelle
165  intv_a = sqrt(k0_value) / 100;
166  std::vector<double> u_alpha(size), integrande_alpha1(size), integrande_alpha2(size);
167  for (int j = 0; j <= 100; j++)
168  {
169  u_alpha.push_back(j * intv_a);
170  double u_value = k0_value - u_alpha[j] * u_alpha[j];
171  double u_2value = 2 * k0_value - u_alpha[j] * u_alpha[j];
172  double expression1a =
173  1.0 / (k0_value * sqrt(u_2value)) *
174  ((k0_value * k0_value + k_value * u_value) * (k0_value * k0_value + k_value * u_value)) *
175  gaussianSpectrum(k_value + u_value, deviation, length);
176  double expression2a =
177  1.0 / (k0_value * sqrt(u_2value)) *
178  ((k0_value * k0_value - k_value * u_value) * (k0_value * k0_value - k_value * u_value)) *
179  gaussianSpectrum(k_value - u_value, deviation, length);
180  integrande_alpha1.push_back(expression1a);
181  integrande_alpha2.push_back(expression2a);
182  }
183  double alpha1 = trapz(u_alpha, integrande_alpha1);
184  double alpha2 = trapz(u_alpha, integrande_alpha2);
185  double alpha = alpha1 + alpha2;
186  Bf.getTabValReel()[i] = alpha;
187  u_alpha.clear();
188  integrande_alpha1.clear();
189  integrande_alpha2.clear();
190 
191  // Partie imaginaire
192  intv_b = (6 / length) / 100; // Condition sur length
193  std::vector<double> u_beta(size), integrande_beta1(size), integrande_beta2(size);
194  for (int j = 0; j <= 100; j++)
195  {
196  u_beta.push_back(j * intv_b);
197  double u_value = k0_value * k0_value + u_beta[j] * u_beta[j];
198  double expression1b = 1.0 / (k0_value * sqrt(u_value)) *
199  (k0_value * k0_value + k_value * sqrt(u_value)) *
200  (k0_value * k0_value + k_value * sqrt(u_value)) *
201  gaussianSpectrum(k_value + sqrt(u_value), deviation, length);
202  double expression2b = 1.0 / (k0_value * sqrt(u_value)) *
203  (k0_value * k0_value - k_value * sqrt(u_value)) *
204  (k0_value * k0_value - k_value * sqrt(u_value)) *
205  gaussianSpectrum(k_value - sqrt(u_value), deviation, length);
206  integrande_beta1.push_back(expression1b);
207  integrande_beta2.push_back(expression2b);
208  }
209  double beta1 = -trapz(u_beta, integrande_beta1);
210  double beta2 = -trapz(u_beta, integrande_beta2);
211  double beta = beta1 + beta2;
212  Bf.getTabValImag()[i] = beta;
213  u_beta.clear();
214  integrande_beta1.clear();
215  integrande_beta2.clear();
216 
217  // Récupération de Zs
218  TYComplex cplxVal;
219  TYComplex Zs_value = TYComplex(Zs.getTabValReel()[i], Zs.getTabValImag()[i]);
220  cplxVal = CPLX_UN / Zs_value;
221 
222  // Calcul de l'impedance effective
223  Bf.getTabValReel()[i] += cplxVal.real();
224  Bf.getTabValImag()[i] += cplxVal.imag();
225 
226  TYComplex ZcplxVal;
227  TYComplex Bf_value = TYComplex(Bf.getTabValReel()[i], Bf.getTabValImag()[i]);
228  ZcplxVal = CPLX_UN / Bf_value;
229 
230  Zf.getTabValReel()[i] = ZcplxVal.real();
231  Zf.getTabValImag()[i] = ZcplxVal.imag();
232  }
234 }
235 
236 double AcousticGroundMaterial::gaussianSpectrum(double k, double sigma, double lc)
237 {
238  return (sigma * sigma) * (lc / (2 * sqrt(M_PI))) * exp(-1.0 / 4 * ((k * lc) * (k * lc)));
239 }
240 
241 double AcousticGroundMaterial::trapz(std::vector<double> u, std::vector<double> integrande)
242 {
243  size_t size = u.size();
244  double sum = std::accumulate(integrande.begin() + 1, integrande.end() - 1,
245  (integrande.front() + integrande.back()) / 2);
246  sum *= (u.back() - u.front()) / size;
247  return sum;
248 }
249 
251 {
252  // const TYComplex CPLX_UN = TYComplex(1.0, 0.0);
253  double sinPhi = sin(angle);
254  TYComplex Z;
255 
256  for (unsigned int i = 0; i < Zs.getNbValues(); i++)
257  {
258  Z = TYComplex(Zs.getTabValReel()[i], Zs.getTabValImag()[i]);
259 
260  TYComplex val = (Z * sinPhi - CPLX_UN) / (Z * sinPhi + CPLX_UN);
261 
262  Rp.getTabValReel()[i] = val.real();
263  Rp.getTabValImag()[i] = val.imag();
264  }
265 }
266 
267 void AcousticGroundMaterial::computeW(double angle, double length, const ComplexSpectrum& Zs,
268  ComplexSpectrum& W)
269 {
270  TYComplex zs_value, invZs_value, cplxTempo, wTemp;
271 
272  double k_value = NAN; // nombre d'onde acoustique
273  double sinPhi = sin(angle);
274 
275  for (unsigned int i = 0; i < W.getNbValues(); i++)
276  {
277  k_value = atmosphere->get_k().getTabValReel()[i];
278  zs_value = TYComplex(Zs.getTabValReel()[i], Zs.getTabValImag()[i]);
279 
280  invZs_value = 1.0 / zs_value;
281  cplxTempo = (sinPhi + invZs_value) * (sinPhi + invZs_value);
282 
283  wTemp = std::sqrt(1.0 / 2.0 * CPLX_J * k_value * length * cplxTempo);
284 
285  W.getTabValReel()[i] = wTemp.real();
286  W.getTabValImag()[i] = wTemp.imag();
287  }
288 }
289 
291 {
292  // localW is intentionnaly a copy of w (values may change)
293 
294  OSpectreComplex G;
295 
296  // Recherche et remplacement des parties reelles et imaginaires < epsilon par epsilon
297  limit_W_values(localW);
298 
299  // Filtrage des differents cas
300  erfc_G_computation(localW, G);
301 
302  // Operations en fonction du signe des parties reelles et imaginaires de w
303  sgn_G_computation(localW, G);
304 
305  // Calcul de la fonction Fw
306  double sqrt_pi = sqrt(M_PI);
307 
308  for (size_t i = 0; i < localW.getNbValues(); i++)
309  {
310  TYComplex v1 = TYComplex(localW.getTabValReel()[i], localW.getTabValImag()[i]);
311  TYComplex v2 = TYComplex(G.getTabValReel()[i], G.getTabValImag()[i]);
312  TYComplex val = CPLX_UN + CPLX_J * sqrt_pi * v1 * v2;
313  Fw.getTabValReel()[i] = val.real();
314  Fw.getTabValImag()[i] = val.imag();
315  }
316 }
317 
319 {
320  const double epsilon = 1.0E-20;
321  double valeur = NAN, tampon = NAN;
322 
323  for (size_t i = 0; i < localW.getNbValues(); i++)
324  {
325  // Si partie reelle < epsilon alors partie reelle = epsilon
326  tampon = localW.getTabValReel()[i];
327  valeur = (fabs(tampon) < epsilon ? epsilon : tampon);
328  localW.getTabValReel()[i] = valeur;
329 
330  // Si partie imaginaire < epsilon alors partie imaginaire = epsilon
331  tampon = localW.getTabValImag()[i];
332  valeur = (fabs(tampon) < epsilon ? epsilon : tampon);
333  localW.getTabValImag()[i] = valeur;
334  }
335 }
336 
338 {
339  double reelW = NAN, imagW = NAN;
340  TYComplex val;
341 
342  for (size_t i = 0; i < localW.getNbValues(); i++)
343  {
344  reelW = localW.getTabValReel()[i];
345  imagW = localW.getTabValImag()[i];
346 
347  if (((fabs(reelW) < 3.9) && (fabs(imagW) < 3.0))) // Cas 1
348  {
349  val = erfcCas1(TYComplex(reelW, imagW));
350  }
351  else if (((fabs(reelW) >= 3.9) && (fabs(reelW) < 6.0)) || // Cas 2
352  ((fabs(imagW) >= 3.0) && (fabs(imagW) < 6.0)))
353  {
354  val = erfcCas2(TYComplex(fabs(reelW), fabs(imagW)));
355  }
356  else // Cas 3
357  {
358  val = erfcCas3(TYComplex(fabs(reelW), fabs(imagW)));
359  }
360 
361  G.getTabValReel()[i] = val.real();
362  G.getTabValImag()[i] = val.imag();
363  }
364 }
365 
367 {
368  double re = NAN, im = NAN;
369  for (size_t i = 0; i < localW.getNbValues(); i++)
370  {
371  re = localW.getTabValReel()[i];
372  im = localW.getTabValImag()[i];
373 
374  TYComplex conjG = conj(TYComplex(G.getTabValReel()[i], G.getTabValImag()[i]));
375 
376  if ((re < 0) && (im > 0)) // imp
377  {
378  G.getTabValReel()[i] = conjG.real();
379  G.getTabValImag()[i] = conjG.imag();
380  }
381  else if ((re > 0) && (im < 0)) // ipm
382  {
383  TYComplex v1 = TYComplex(localW.getTabValReel()[i], localW.getTabValImag()[i]);
384  TYComplex v2 = TYComplex(G.getTabValReel()[i], G.getTabValImag()[i]);
385  TYComplex tampon = sgnReIm(v1, v2);
386 
387  G.getTabValReel()[i] = tampon.real();
388  G.getTabValImag()[i] = tampon.imag();
389  ;
390  }
391  else if ((re < 0) && (im < 0)) // imm
392  {
393  TYComplex v1 = TYComplex(localW.getTabValReel()[i], localW.getTabValImag()[i]);
394  TYComplex v2 = TYComplex(G.getTabValReel()[i], G.getTabValImag()[i]);
395  TYComplex tampon = sgnReIm(v1, v2);
396 
397  TYComplex val = conj(tampon);
398 
399  G.getTabValReel()[i] = val.real();
400  G.getTabValImag()[i] = val.imag();
401  }
402  else if ((re > 0) && (im > 0)) // ipp
403  {
404  }
405  else
406  {
407  }
408  }
409 }
410 
412  ComplexSpectrum& Q)
413 {
414  TYComplex Rp_value, Fw_value;
415 
416  for (unsigned int i = 0; i < Fw.getNbValues(); i++)
417  {
418  Rp_value = TYComplex(Rp.getTabValReel()[i], Rp.getTabValImag()[i]);
419  Fw_value = TYComplex(Fw.getTabValReel()[i], Fw.getTabValImag()[i]);
420 
421  TYComplex val = Rp_value + (CPLX_UN - Rp_value) * Fw_value;
422 
423  Q.getTabValReel()[i] = val.real();
424  Q.getTabValImag()[i] = val.imag();
425  }
426 }
427 
429 {
430  const double pi = M_PI;
431  const int nbIterations = 5; // Valeur normale = 5
432  const double h = 0.8; // valeur proposee = 0.8;
433  const double h2 = h * h;
434 
435  double x = fabs(wValue.real());
436  double y = fabs(wValue.imag());
437  double x2 = x * x;
438  double y2 = y * y;
439  double modW = x2 + y2;
440 
441  double A1 = cos(2.0 * x * y);
442  double B1 = sin(2.0 * x * y);
443  double C1 = exp(-2.0 * pi * y / h) - cos(2.0 * pi * x / h);
444  double D1 = sin(2.0 * pi * x / h);
445  double P2 = 2.0 * exp(-(x2 + 2.0 * pi * y / h - y2)) * (A1 * C1 - B1 * D1) / (C1 * C1 + D1 * D1);
446  double Q2 = 2.0 * exp(-(x2 + 2.0 * pi * y / h - y2)) * (A1 * D1 + B1 * C1) / (C1 * C1 + D1 * D1);
447 
448  double H0 = NAN, H = NAN, K0 = NAN, K = NAN;
449 
450  if (y < (pi / h))
451  {
452  H0 = h * y / (pi * modW) + P2;
453  }
454  else if (y == (pi / h))
455  {
456  H0 = h * y / (pi * modW) + (P2 / 2.0);
457  }
458  else
459  {
460  H0 = h * y / (pi * modW);
461  }
462 
463  if (x < (pi / h))
464  {
465  K0 = h * x / (pi * modW) - Q2;
466  }
467  else if (x == (pi / h))
468  {
469  K0 = h * x / (pi * modW) - (Q2 / 2.0);
470  }
471  else
472  {
473  K0 = h * x / (pi * modW);
474  }
475 
476  /* Solution MATLAB */
477  H = H0;
478  K = K0;
479  double n2 = 0.0;
480  double coeff_y = 2.0 * y * h / pi;
481  double coeff_x = 2.0 * x * h / pi;
482  double diviseur = 0.0;
483  double expMn2h2 = 0.0;
484  for (int n = 1; n <= nbIterations; n++)
485  {
486  n2 = (double)(n * n);
487  diviseur = ((y2 - x2 + n2 * h2) * (y2 - x2 + n2 * h2) + (4.0 * y2 * x2));
488  expMn2h2 = exp(-n2 * h2);
489 
490  H = H + coeff_y * expMn2h2 * (modW + n2 * h2) / diviseur;
491  K = K + coeff_x * expMn2h2 * (modW - n2 * h2) / diviseur;
492  }
493 
494  return TYComplex(H, K);
495 }
496 
498 {
499  TYComplex G;
500  TYComplex w2 = wValue * wValue;
501 
502  G = CPLX_J * wValue *
503  ((0.4613135 / (w2 - 0.1901635)) + (0.09999216 / (w2 - 1.7844927)) + (0.002883894 / (w2 - 5.5253437)));
504 
505  return G;
506 }
507 
509 {
510  TYComplex G;
511 
512  TYComplex w2 = wValue * wValue;
513 
514  G = CPLX_J * wValue * ((0.5124242 / (w2 - 0.2752551)) + (0.05176536 / (w2 - 2.724745)));
515 
516  return G;
517 }
518 
520 {
521  double x = fabs(W.real());
522  double y = fabs(W.imag());
523 
524  double cos2xy = cos(2 * x * y);
525  double sin2xy = sin(2 * x * y);
526 
527  return 2.0 * exp(y * y - x * x) * (cos2xy + CPLX_J * sin2xy) - conj(G);
528 }
529 
530 // ---------
531 
533 
534 // ---------
535 /*static*/ const double VolumeFaceDirectivity::_tabRA[] = {
536  1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 100.0, 200.0, 300.0,
537 };
538 /*static*/ const double VolumeFaceDirectivity::_tabCor[] = {0.608, 0.817, 0.879, 0.909, 0.928, 0.964, 0.982,
539  0.988, 0.991, 0.993, 0.996, 0.998, 1.000};
540 double VolumeFaceDirectivity::calculC(double distance)
541 {
542  double X = distance / support_size;
543 
544  if (X < 1.0)
545  {
546  return _tabCor[0];
547  }
548  if (X > 300.0)
549  {
550  return 1.0;
551  }
552 
553  int i = 1;
554  while (_tabRA[i] < X && i < 12)
555  {
556  i++;
557  } // Recherche de l'indice le plus proche
558 
559  // Calcul de la valeur de c par interpolation lineaire
560  return (_tabCor[i] - _tabCor[i - 1]) / (_tabRA[i] - _tabRA[i - 1]) * (X - _tabRA[i - 1]) + _tabCor[i - 1];
561 }
562 
564 {
565  Spectrum directivity_spectrum;
566  double q = NAN, ka = NAN;
567 
568  // Angle angle between support normal and (source to receptor) vector
569  double cosPhi = cos(support_normal.angle(direction));
570 
571  double C = calculC(distance); // Coefficient de directivite
572 
573  for (unsigned int i = 0; i < directivity_spectrum.getNbValues(); i++)
574  {
576 
577  q = (1 + (ka / (ka + 0.4)) * cosPhi) * C;
578 
579  directivity_spectrum.getTabValReel()[i] = q;
580  }
581 
582  return directivity_spectrum;
583 }
584 //
585 // ----------------------------------------
586 //
587 #ifdef NB_KA
588  #undef NB_KA
589  #define NB_KA 38
590 #else
591  #define NB_KA 38
592 #endif
593 
594 #ifdef NB_THETA
595  #undef NB_THETA
596  #define NB_THETA 21
597 #else
598  #define NB_THETA 21
599 #endif
601  {/*ka1*/ 3.9213E-02, 3.8299E-02, 3.5626E-02, 3.1399E-02, 2.5933E-02, 1.9633E-02,
602  1.2955E-02, 6.3631E-03, 2.9321E-04, -4.8880E-03, -8.9124E-03, -1.1631E-02,
603  -1.3023E-02, -1.3192E-02, -1.2351E-02, -1.0793E-02, -8.8587E-03, -6.8993E-03,
604  -5.2361E-03, -4.1269E-03, -3.7380E-03},
605  {/*ka2*/ 1.5295E-01, 1.4940E-01, 1.3903E-01, 1.2260E-01, 1.0132E-01, 7.6753E-02,
606  5.0654E-02, 2.4837E-02, 1.0112E-03, -1.9370E-02, -3.5229E-02, -4.5960E-02,
607  -5.1463E-02, -5.2134E-02, -4.8805E-02, -4.2637E-02, -3.4980E-02, -2.7223E-02,
608  -2.0640E-02, -1.6250E-02, -1.4711E-02},
609  {/*ka3*/ 3.3341E-01, 3.2573E-01, 3.0323E-01, 2.6755E-01, 2.2126E-01, 1.6765E-01,
610  1.1054E-01, 5.3866E-02, 1.4017E-03, -4.3595E-02, -7.8677E-02, -1.0242E-01,
611  -1.1455E-01, -1.1590E-01, -1.0831E-01, -9.4383E-02, -7.7136E-02, -5.9688E-02,
612  -4.4893E-02, -3.5032E-02, -3.1576E-02},
613  {/*ka4*/ 5.7143E-01, 5.5835E-01, 5.2003E-01, 4.5914E-01, 3.7992E-01, 2.8790E-01,
614  1.8948E-01, 9.1440E-02, 3.3045E-04, -7.8073E-02, -1.3934E-01, -1.8081E-01,
615  -2.0183E-01, -2.0382E-01, -1.8997E-01, -1.6488E-01, -1.3394E-01, -1.0271E-01,
616  -7.6267E-02, -5.8657E-02, -5.2487E-02},
617  {/*ka5*/ 8.5759E-01, 8.3811E-01, 7.8096E-01, 6.8997E-01, 5.7125E-01, 4.3285E-01,
618  2.8419E-01, 1.3542E-01, -3.4683E-03, -1.2348E-01, -2.1752E-01, -2.8120E-01,
619  -3.1323E-01, -3.1559E-01, -2.9322E-01, -2.5329E-01, -2.0429E-01, -1.5494E-01,
620  -1.1321E-01, -8.5459E-02, -7.5741E-02},
621  {/*ka6*/ 1.1831E+00, 1.1564E+00, 1.0781E+00, 9.5307E-01, 7.8950E-01, 5.9808E-01,
622  3.9154E-01, 1.8377E-01, -1.1197E-02, -1.8049E-01, -3.1367E-01, -4.0394E-01,
623  -4.4902E-01, -4.5143E-01, -4.1811E-01, -3.5943E-01, -2.8771E-01, -2.1567E-01,
624  -1.5487E-01, -1.1446E-01, -1.0033E-01},
625  {/*ka7*/ 1.5403E+00, 1.5058E+00, 1.4044E+00, 1.2424E+00, 1.0296E+00, 7.7974E-01,
626  5.0881E-01, 2.3480E-01, -2.3835E-02, -2.4970E-01, -4.2827E-01, -5.4964E-01,
627  -6.0999E-01, -6.1221E-01, -5.6552E-01, -4.8406E-01, -3.8483E-01, -2.8537E-01,
628  -2.0156E-01, -1.4594E-01, -1.2649E-01},
629  {/*ka8*/ 1.9232E+00, 1.8805E+00, 1.7546E+00, 1.5530E+00, 1.2876E+00, 9.7474E-01,
630  6.3391E-01, 2.8725E-01, -4.2025E-02, -3.3151E-01, -5.6184E-01, -7.1921E-01,
631  -7.9754E-01, -7.9976E-01, -7.3751E-01, -6.2935E-01, -4.9783E-01, -3.6618E-01,
632  -2.5541E-01, -1.8197E-01, -1.5631E-01},
633  {/*ka9*/ 2.3273E+00, 2.2758E+00, 2.1243E+00, 1.8812E+00, 1.5605E+00, 1.1808E+00,
634  7.6540E-01, 3.4042E-01, -6.6025E-02, -4.2610E-01, -7.1493E-01, -9.1390E-01,
635  -1.0138E+00, -1.0170E+00, -9.3769E-01, -7.9931E-01, -6.3089E-01, -4.6239E-01,
636  -3.2076E-01, -2.2695E-01, -1.9418E-01},
637  {/*ka10*/ 2.7492E+00, 2.6887E+00, 2.5106E+00, 2.2244E+00, 1.8459E+00, 1.3965E+00,
638  9.0236E-01, 3.9399E-01, -9.5749E-02, -5.3340E-01, -8.8806E-01, -1.1353E+00,
639  -1.2618E+00, -1.2684E+00, -1.1715E+00, -1.0001E+00, -7.9063E-01, -5.8088E-01,
640  -4.0461E-01, -2.8794E-01, -2.4721E-01},
641  {/*ka11*/ 3.1894E+00, 3.1197E+00, 2.9141E+00, 2.5834E+00, 2.1451E+00, 1.6229E+00,
642  1.0464E+00, 4.4972E-01, -1.2959E-01, -6.5256E-01, -1.0819E+00, -1.3865E+00,
643  -1.5474E+00, -1.5627E+00, -1.4504E+00, -1.2450E+00, -9.9164E-01, -7.3698E-01,
644  -5.2275E-01, -3.8095E-01, -3.3145E-01},
645  {/*ka12*/ 3.6467E+00, 3.5674E+00, 3.3337E+00, 2.9572E+00, 2.4572E+00, 1.8599E+00,
646  1.1978E+00, 5.0838E-01, -1.6650E-01, -7.8278E-01, -1.2969E+00, -1.6703E+00,
647  -1.8769E+00, -1.9100E+00, -1.7875E+00, -1.5497E+00, -1.2509E+00, -9.4848E-01,
648  -6.9332E-01, -5.2427E-01, -4.6524E-01},
649  {/*ka13*/ 4.0966E+00, 4.0077E+00, 3.7455E+00, 3.3227E+00, 2.7605E+00, 2.0874E+00,
650  1.3388E+00, 5.5573E-01, -2.1615E-01, -9.2821E-01, -1.5310E+00, -1.9786E+00,
651  -2.2366E+00, -2.2918E+00, -2.1605E+00, -1.8882E+00, -1.5398E+00, -1.1845E+00,
652  -8.8398E-01, -6.8475E-01, -6.1517E-01},
653  {/*ka14*/ 4.5369E+00, 4.4382E+00, 4.1471E+00, 3.6774E+00, 3.0522E+00, 2.3026E+00,
654  1.4670E+00, 5.8981E-01, -2.7973E-01, -1.0889E+00, -1.7833E+00, -2.3100E+00,
655  -2.6256E+00, -2.7083E+00, -2.5709E+00, -2.2632E+00, -1.8614E+00, -1.4484E+00,
656  -1.0982E+00, -8.6591E-01, -7.8478E-01},
657  {/*ka15*/ 4.9652E+00, 4.8566E+00, 4.5361E+00, 4.0188E+00, 3.3298E+00, 2.5030E+00,
658  1.5798E+00, 6.0833E-01, -3.5883E-01, -1.2655E+00, -2.0530E+00, -2.6626E+00,
659  -3.0418E+00, -3.1586E+00, -3.0192E+00, -2.6764E+00, -2.2180E+00, -1.7428E+00,
660  -1.3386E+00, -1.0703E+00, -9.7666E-01},
661  {/*ka16*/ 5.3802E+00, 5.2615E+00, 4.9111E+00, 4.3454E+00, 3.5916E+00, 2.6865E+00,
662  1.6752E+00, 6.0927E-01, -4.5493E-01, -1.4582E+00, -2.3388E+00, -3.0336E+00,
663  -3.4819E+00, -3.6400E+00, -3.5043E+00, -3.1278E+00, -2.6105E+00, -2.0689E+00,
664  -1.6065E+00, -1.2994E+00, -1.1921E+00},
665  {/*ka17*/ 5.7809E+00, 5.6519E+00, 5.2709E+00, 4.6558E+00, 3.8360E+00, 2.8514E+00,
666  1.7510E+00, 5.9048E-01, -5.6989E-01, -1.6679E+00, -2.6400E+00, -3.4203E+00,
667  -3.9418E+00, -4.1484E+00, -4.0235E+00, -3.6166E+00, -3.0391E+00, -2.4271E+00,
668  -1.9025E+00, -1.5536E+00, -1.4318E+00},
669  {/*ka18*/ 6.1672E+00, 6.0276E+00, 5.6153E+00, 4.9496E+00, 4.0623E+00, 2.9966E+00,
670  1.8057E+00, 5.5010E-01, -7.0558E-01, -1.8960E+00, -2.9562E+00, -3.8199E+00,
671  -4.4165E+00, -4.6786E+00, -4.5731E+00, -4.1408E+00, -3.5029E+00, -2.8170E+00,
672  -2.2262E+00, -1.8328E+00, -1.6954E+00},
673  {/*ka19*/ 6.5395E+00, 6.3890E+00, 5.9446E+00, 5.2269E+00, 4.2703E+00, 3.1214E+00,
674  1.8382E+00, 4.8645E-01, -8.6398E-01, -2.1439E+00, -3.2877E+00, -4.2304E+00,
675  -4.9013E+00, -5.2244E+00, -5.1475E+00, -4.6969E+00, -4.0000E+00, -3.2376E+00,
676  -2.5767E+00, -2.1360E+00, -1.9820E+00},
677  {/*ka20*/ 6.8987E+00, 6.7370E+00, 6.2595E+00, 5.4883E+00, 4.4602E+00, 3.2257E+00,
678  1.8476E+00, 3.9797E-01, -1.0472E+00, -2.4141E+00, -3.6356E+00, -4.6504E+00,
679  -5.3917E+00, -5.7788E+00, -5.7401E+00, -5.2805E+00, -4.5278E+00, -3.6868E+00,
680  -2.9524E+00, -2.4616E+00, -2.2901E+00},
681  {/*ka21*/ 7.2462E+00, 7.0730E+00, 6.5614E+00, 5.7349E+00, 4.6328E+00, 3.3096E+00,
682  1.8335E+00, 2.8322E-01, -1.2576E+00, -2.7091E+00, -4.0024E+00, -5.0802E+00,
683  -5.8841E+00, -6.3348E+00, -6.3433E+00, -5.8859E+00, -5.0828E+00, -4.1626E+00,
684  -3.3514E+00, -2.8078E+00, -2.6178E+00},
685  {/*ka22*/ 7.5836E+00, 7.3985E+00, 6.8516E+00, 5.9679E+00, 4.7890E+00, 3.3735E+00,
686  1.7953E+00, 1.4071E-01, -1.4979E+00, -3.0326E+00, -4.3913E+00, -5.5215E+00,
687  -6.3766E+00, -6.8863E+00, -6.9488E+00, -6.5063E+00, -5.6609E+00, -4.6621E+00,
688  -3.7715E+00, -3.1726E+00, -2.9630E+00},
689  {/*ka23*/ 7.9125E+00, 7.7152E+00, 7.1317E+00, 6.1886E+00, 4.9299E+00, 3.4179E+00,
690  1.7326E+00, -3.1215E-02, -1.7709E+00, -3.3886E+00, -4.8069E+00, -5.9777E+00,
691  -6.8694E+00, -7.4281E+00, -7.5480E+00, -7.1343E+00, -6.2574E+00, -5.1825E+00,
692  -4.2103E+00, -3.5537E+00, -3.3237E+00},
693  {/*ka24*/ 8.2345E+00, 8.0244E+00, 7.4032E+00, 6.3983E+00, 5.0563E+00, 3.4431E+00,
694  1.6449E+00, -2.3448E-01, -2.0804E+00, -3.7824E+00, -5.2552E+00, -6.4540E+00,
695  -7.3646E+00, -7.9573E+00, -8.1330E+00, -7.7614E+00, -6.8670E+00, -5.7206E+00,
696  -4.6657E+00, -3.9491E+00, -3.6977E+00},
697  {/*ka25*/ 8.5510E+00, 8.3278E+00, 7.6673E+00, 6.5982E+00, 5.1690E+00, 3.4493E+00,
698  1.5312E+00, -4.7147E-01, -2.4305E+00, -4.2200E+00, -5.7434E+00, -6.9574E+00,
699  -7.8668E+00, -8.4733E+00, -8.6970E+00, -8.3789E+00, -7.4837E+00, -6.2733E+00,
700  -5.1355E+00, -4.3570E+00, -4.0835E+00},
701  {/*ka26*/ 8.8632E+00, 8.6262E+00, 7.9252E+00, 6.7892E+00, 5.2687E+00, 3.4364E+00,
702  1.3906E+00, -7.4501E-01, -2.8265E+00, -4.7089E+00, -6.2803E+00, -7.4966E+00,
703  -8.3829E+00, -8.9783E+00, -9.2352E+00, -8.9780E+00, -8.1010E+00, -6.8372E+00,
704  -5.6177E+00, -4.7758E+00, -4.4793E+00},
705  {/*ka27*/ 9.1717E+00, 8.9207E+00, 8.1775E+00, 6.9719E+00, 5.3555E+00, 3.4041E+00,
706  1.2212E+00, -1.0587E+00, -3.2745E+00, -5.2580E+00, -6.8767E+00, -8.0824E+00,
707  -8.9219E+00, -9.4773E+00, -9.7454E+00, -9.5504E+00, -8.7116E+00, -7.4086E+00,
708  -6.1105E+00, -5.2042E+00, -4.8840E+00},
709  {/*ka28*/ 9.4773E+00, 9.2117E+00, 8.4247E+00, 7.1465E+00, 5.4296E+00, 3.3517E+00,
710  1.0212E+00, -1.4170E+00, -3.7824E+00, -5.8785E+00, -7.5458E+00, -8.7278E+00,
711  -9.4948E+00, -9.9776E+00, -1.0228E+01, -1.0089E+01, -9.3081E+00, -7.9839E+00,
712  -6.6123E+00, -5.6413E+00, -5.2969E+00},
713  {/*ka29*/ 9.7800E+00, 9.4993E+00, 8.6669E+00, 7.3131E+00, 5.4905E+00, 3.2779E+00,
714  7.8776E-01, -1.8253E+00, -4.3595E+00, -6.5844E+00, -8.3040E+00, -9.4487E+00,
715  -1.0115E+01, -1.0489E+01, -1.0688E+01, -1.0589E+01, -9.8825E+00, -8.5589E+00,
716  -7.1217E+00, -6.0864E+00, -5.7173E+00},
717  {/*ka30*/ 1.0080E+01, 9.7834E+00, 8.9039E+00, 7.4713E+00, 5.5375E+00, 3.1815E+00,
718  5.1771E-01, -2.2903E+00, -5.0181E+00, -7.3937E+00, -9.1727E+00, -1.0265E+01,
719  -1.0798E+01, -1.1024E+01, -1.1130E+01, -1.1049E+01, -1.0427E+01, -9.1291E+00,
720  -7.6373E+00, -6.5392E+00, -6.1452E+00},
721  {/*ka31*/ 1.0376E+01, 1.0064E+01, 9.1354E+00, 7.6206E+00, 5.5698E+00, 3.0605E+00,
722  2.0709E-01, -2.8202E+00, -5.7735E+00, -8.3303E+00, -1.0180E+01, -1.1202E+01,
723  -1.1563E+01, -1.1594E+01, -1.1565E+01, -1.1468E+01, -1.0935E+01, -9.6893E+00,
724  -8.1576E+00, -6.9995E+00, -6.5807E+00},
725  {/*ka32*/ 1.0668E+01, 1.0339E+01, 9.3604E+00, 7.7600E+00, 5.5861E+00, 2.9127E+00,
726  -1.4879E-01, -3.4253E+00, -6.6463E+00, -9.4274E+00, -1.1367E+01, -1.2295E+01,
727  -1.2433E+01, -1.2217E+01, -1.2003E+01, -1.1852E+01, -1.1400E+01, -1.0234E+01,
728  -8.6812E+00, -7.4676E+00, -7.0243E+00},
729  {/*ka33*/ 1.0956E+01, 1.0609E+01, 9.5782E+00, 7.8886E+00, 5.5849E+00, 2.7355E+00,
730  -5.5553E-01, -4.1185E+00, -7.6641E+00, -1.0733E+01, -1.2791E+01, -1.3593E+01,
731  -1.3439E+01, -1.2909E+01, -1.2457E+01, -1.2206E+01, -1.1820E+01, -1.0758E+01,
732  -9.2063E+00, -7.9436E+00, -7.4766E+00},
733  {/*ka34*/ 1.1237E+01, 1.0873E+01, 9.7877E+00, 8.0051E+00, 5.5648E+00, 2.5261E+00,
734  -1.0198E+00, -4.9166E+00, -8.8666E+00, -1.2322E+01, -1.4549E+01, -1.5171E+01,
735  -1.4623E+01, -1.3692E+01, -1.2939E+01, -1.2540E+01, -1.2193E+01, -1.1254E+01,
736  -9.7309E+00, -8.4279E+00, -7.9385E+00},
737  {/*ka35*/ 1.1512E+01, 1.1129E+01, 9.9878E+00, 8.1084E+00, 5.5239E+00, 2.2812E+00,
738  -1.5494E+00, -5.8416E+00, -1.0313E+01, -1.4320E+01, -1.6807E+01, -1.7156E+01,
739  -1.6046E+01, -1.4592E+01, -1.3464E+01, -1.2864E+01, -1.2521E+01, -1.1718E+01,
740  -1.0253E+01, -8.9208E+00, -8.4107E+00},
741  {/*ka36*/ 1.1778E+01, 1.1376E+01, 1.0177E+01, 8.1972E+00, 5.4605E+00, 1.9974E+00,
742  -2.1540E+00, -6.9238E+00, -1.2098E+01, -1.6967E+01, -1.9918E+01, -1.9789E+01,
743  -1.7805E+01, -1.5641E+01, -1.4046E+01, -1.3190E+01, -1.2810E+01, -1.2145E+01,
744  -1.0769E+01, -9.4225E+00, -8.8943E+00},
745  {/*ka37*/ 1.2035E+01, 1.1614E+01, 1.0355E+01, 8.2703E+00, 5.3729E+00, 1.6709E+00,
746  -2.8454E+00, -8.2070E+00, -1.4393E+01, -2.0830E+01, -2.4847E+01, -2.3638E+01,
747  -2.0073E+01, -1.6886E+01, -1.4703E+01, -1.3528E+01, -1.3066E+01, -1.2530E+01,
748  -1.1275E+01, -9.9329E+00, -9.3900E+00},
749  {/*ka38*/ 1.2282E+01, 1.1841E+01, 1.0521E+01, 8.3267E+00, 5.2594E+00, 1.2974E+00,
750  -3.6384E+00, -9.7578E+00, -1.7557E+01, -2.7951E+01, -3.7266E+01, -3.0744E+01,
751  -2.3208E+01, -1.8396E+01, -1.5453E+01, -1.3891E+01, -1.3297E+01, -1.2873E+01,
752  -1.1769E+01, -1.0452E+01, -9.8987E+00}};
753 
755 {
756  Spectrum directivity_spectrum;
757 
758  Spectrum spectre_ka = atmosphere->get_k().mult(support_size);
759 
760  double theta =
761  direction.angle(support_normal); // Angle du segment par rapport a la normale au support de la source
762 
763  // angle compris entre 0 et pi
764  if (theta < -M_PI)
765  {
766  theta = theta + M_2PI;
767  }
768  if (theta > M_PI)
769  {
770  theta = theta - M_2PI;
771  }
772  theta = ABS(theta); // On prend la valeur absolue de theta
773 
774  int indice_theta = (int)(20 * theta / M_PI); // Indice de l'angle theta dans le tableau
775  for (unsigned int i = 0; i < spectre_ka.getNbValues(); i++)
776  {
777  double ka = spectre_ka.getTabValReel()[i];
778  ka = ka > 3.8 ? 3.8 : ka;
779  int indice_Ka = (int)(10 * ka);
780 
781  directivity_spectrum.getTabValReel()[i] = compute_q(indice_Ka, indice_theta, ka, theta);
782  }
783 
784  return directivity_spectrum;
785 }
786 
787 double ChimneyFaceDirectivity::compute_q(int ka_idx, int theta_idx, double ka, double theta)
788 {
789  /* ===========================================================================================
790  Recherche par interpolation lineaire dans le tableau _tabQ
791  de la valeur de Q la plus proche
792  ===========================================================================================*/
793  int indiceKaTab = ka_idx > 0 ? ka_idx - 1 : 0; // Eviter les depassement de tableau
794  indiceKaTab = indiceKaTab > (NB_KA - 2) ? NB_KA - 2 : indiceKaTab; // Eviter les depassement de tableau
795 
796  double tabQ1_1 = _tabQ[indiceKaTab][theta_idx]; //_tabQ[indice_Ka] [indice_theta]
797  double tabQ1_2 = _tabQ[indiceKaTab][theta_idx + 1]; //_tabQ[indice_Ka] [indice_theta+1]
798  double tabQ2_1 = _tabQ[indiceKaTab + 1][theta_idx]; //_tabQ[indice_Ka+1][indice_theta]
799  double tabQ2_2 = _tabQ[indiceKaTab + 1][theta_idx + 1]; //_tabQ[indice_Ka+1][indice_theta+1]
800 
801  double ka1 = ka_idx / 10.0;
802  double ka2 = (ka_idx + 1) / 10.0;
803 
804  double theta1 = theta_idx * M_PI / 20.0;
805  double theta2 = (theta_idx + 1) * M_PI / 20.0;
806 
807  double val1 = tabQ1_1 + (theta - theta1) * (tabQ1_2 - tabQ1_1) / (theta2 - theta1);
808  double val2 = tabQ2_1 + (theta - theta1) * (tabQ2_2 - tabQ2_1) / (theta2 - theta1);
809 
810  double val = val1 + (ka2 - ka) * (val2 - val1) / (ka2 - ka1);
811 
812  return pow(10.0, val / 10.0);
813 }
814 //
815 // --------------------------
816 //
817 #ifdef NB_KA
818  #undef NB_KA
819  #define NB_KA 9
820 #else
821  #define NB_KA 9
822 #endif
823 
824 // nombre de valeurs de theta dans le tableau
825 #ifdef NB_THETA
826  #undef NB_THETA
827  #define NB_THETA 41
828 #else
829  #define NB_THETA 41
830 #endif
831 
832 const double BaffledFaceDirectivity::_tabKa[NB_KA] = {0.05, 0.1, 0.25, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0};
833 
835  {/*ka=0,05*/ 2.0382E+00,
836  2.0382E+00,
837  1.7752E+00,
838  1.7752E+00,
839  2.0382E+00,
840  2.0382E+00,
841  1.6953E+00,
842  1.4101E+00,
843  1.2860E+00,
844  1.1729E+00,
845  8.1142E-01,
846  6.0152E-01,
847  4.4591E-01,
848  3.3056E-01,
849  2.4505E-01,
850  1.8165E-01,
851  1.3466E-01,
852  9.9827E-02,
853  7.4003E-02,
854  5.4859E-02,
855  4.0667E-02,
856  5.4859E-02,
857  7.4003E-02,
858  9.9827E-02,
859  1.3466E-01,
860  1.8165E-01,
861  2.4505E-01,
862  3.3056E-01,
863  4.4591E-01,
864  6.0152E-01,
865  8.1142E-01,
866  1.1729E+00,
867  1.2860E+00,
868  1.4101E+00,
869  1.6953E+00,
870  2.0382E+00,
871  2.0382E+00,
872  1.7752E+00,
873  1.7752E+00,
874  2.0382E+00,
875  2.0382E+00},
876  {/*ka=0,1*/ 1.0215E+00,
877  1.0215E+00,
878  1.0215E+00,
879  1.1201E+00,
880  1.2860E+00,
881  1.2860E+00,
882  1.2860E+00,
883  1.4765E+00,
884  1.6190E+00,
885  1.6190E+00,
886  1.6190E+00,
887  1.1201E+00,
888  7.7490E-01,
889  5.3610E-01,
890  3.7089E-01,
891  2.5659E-01,
892  1.7752E-01,
893  1.2281E-01,
894  8.4966E-02,
895  5.8782E-02,
896  4.0667E-02,
897  5.8782E-02,
898  8.4966E-02,
899  1.2281E-01,
900  1.7752E-01,
901  2.5659E-01,
902  3.7089E-01,
903  5.3610E-01,
904  7.7490E-01,
905  1.1201E+00,
906  1.6190E+00,
907  1.6190E+00,
908  1.6190E+00,
909  1.4765E+00,
910  1.2860E+00,
911  1.2860E+00,
912  1.2860E+00,
913  1.1201E+00,
914  1.0215E+00,
915  1.0215E+00,
916  1.0215E+00},
917  {/*ka=0,25*/ 2.1534E+00,
918  1.7911E+00,
919  1.4898E+00,
920  1.3587E+00,
921  1.4227E+00,
922  1.7105E+00,
923  1.7105E+00,
924  1.4898E+00,
925  1.3587E+00,
926  1.3587E+00,
927  1.3587E+00,
928  9.6189E-01,
929  6.8096E-01,
930  4.8209E-01,
931  3.4129E-01,
932  2.4162E-01,
933  1.7105E-01,
934  1.2109E-01,
935  8.5728E-02,
936  6.0691E-02,
937  4.2966E-02,
938  6.0691E-02,
939  8.5728E-02,
940  1.2109E-01,
941  1.7105E-01,
942  2.4162E-01,
943  3.4129E-01,
944  4.8209E-01,
945  6.8096E-01,
946  9.6189E-01,
947  1.3587E+00,
948  1.3587E+00,
949  1.3587E+00,
950  1.4898E+00,
951  1.7105E+00,
952  1.7105E+00,
953  1.4227E+00,
954  1.3587E+00,
955  1.4898E+00,
956  1.7911E+00,
957  2.1534E+00},
958  {/*ka=0,5*/ 1.4385E+00,
959  1.4385E+00,
960  1.4385E+00,
961  1.5773E+00,
962  1.8109E+00,
963  1.8109E+00,
964  2.1772E+00,
965  1.9857E+00,
966  1.5063E+00,
967  1.0912E+00,
968  9.0762E-01,
969  6.7283E-01,
970  4.9877E-01,
971  3.6975E-01,
972  2.7410E-01,
973  2.0319E-01,
974  1.5063E-01,
975  1.1166E-01,
976  8.2776E-02,
977  6.1363E-02,
978  4.5489E-02,
979  6.1363E-02,
980  8.2776E-02,
981  1.1166E-01,
982  1.5063E-01,
983  2.0319E-01,
984  2.7410E-01,
985  3.6975E-01,
986  4.9877E-01,
987  6.7283E-01,
988  9.0762E-01,
989  1.0912E+00,
990  1.5063E+00,
991  1.9857E+00,
992  2.1772E+00,
993  1.8109E+00,
994  1.8109E+00,
995  1.5773E+00,
996  1.4385E+00,
997  1.4385E+00,
998  1.4385E+00},
999  {/*ka=1*/ 3.5678E+00, 4.2895E+00, 4.4916E+00, 3.7360E+00, 2.7065E+00, 2.2511E+00, 1.2954E+00,
1000  8.5586E-01, 7.8055E-01, 8.5586E-01, 7.1187E-01, 5.4001E-01, 4.0964E-01, 3.1074E-01,
1001  2.3572E-01, 1.7881E-01, 1.3564E-01, 1.0290E-01, 7.8055E-02, 5.9211E-02, 4.4916E-02,
1002  5.9211E-02, 7.8055E-02, 1.0290E-01, 1.3564E-01, 1.7881E-01, 2.3572E-01, 3.1074E-01,
1003  4.0964E-01, 5.4001E-01, 7.1187E-01, 8.5586E-01, 7.8055E-01, 8.5586E-01, 1.2954E+00,
1004  2.2511E+00, 2.7065E+00, 3.7360E+00, 4.4916E+00, 4.2895E+00, 3.5678E+00},
1005  {/*ka=2*/ 1.1891E+01, 9.8907E+00, 7.1652E+00, 4.5209E+00, 2.6015E+00, 1.4970E+00, 1.2452E+00,
1006  7.8565E-01, 5.4353E-01, 4.5209E-01, 3.7603E-01, 3.0565E-01, 2.4844E-01, 2.0194E-01,
1007  1.6414E-01, 1.3342E-01, 1.0845E-01, 8.8151E-02, 7.1652E-02, 5.8241E-02, 4.7340E-02,
1008  5.8241E-02, 7.1652E-02, 8.8151E-02, 1.0845E-01, 1.3342E-01, 1.6414E-01, 2.0194E-01,
1009  2.4844E-01, 3.0565E-01, 3.7603E-01, 4.5209E-01, 5.4353E-01, 7.8565E-01, 1.2452E+00,
1010  1.4970E+00, 2.6015E+00, 4.5209E+00, 7.1652E+00, 9.8907E+00, 1.1891E+01},
1011  {/*ka=5*/ 4.5941E+00, 4.5941E+00, 4.5941E+00, 4.1899E+00, 3.1784E+00, 1.8290E+00, 1.2653E+00,
1012  1.0051E+00, 8.3600E-01, 6.9535E-01, 5.7837E-01, 4.4896E-01, 3.4850E-01, 2.7052E-01,
1013  2.0999E-01, 1.6301E-01, 1.2653E-01, 9.8221E-02, 7.6244E-02, 5.9184E-02, 4.5941E-02,
1014  5.9184E-02, 7.6244E-02, 9.8221E-02, 1.2653E-01, 1.6301E-01, 2.0999E-01, 2.7052E-01,
1015  3.4850E-01, 4.4896E-01, 5.7837E-01, 6.9535E-01, 8.3600E-01, 1.0051E+00, 1.2653E+00,
1016  1.8290E+00, 3.1784E+00, 4.1899E+00, 4.5941E+00, 4.5941E+00, 4.5941E+00},
1017  {/*ka=10*/ 3.8007E+00, 3.1613E+00, 3.0190E+00, 2.7534E+00, 2.3981E+00, 2.3981E+00, 1.9946E+00,
1018  1.4450E+00, 1.0961E+00, 8.7070E-01, 6.0237E-01, 4.6759E-01, 3.6297E-01, 2.8175E-01,
1019  2.1871E-01, 1.6977E-01, 1.3179E-01, 1.0230E-01, 7.9408E-02, 6.1641E-02, 4.7848E-02,
1020  6.1641E-02, 7.9408E-02, 1.0230E-01, 1.3179E-01, 1.6977E-01, 2.1871E-01, 2.8175E-01,
1021  3.6297E-01, 4.6759E-01, 6.0237E-01, 8.7070E-01, 1.0961E+00, 1.4450E+00, 1.9946E+00,
1022  2.3981E+00, 2.3981E+00, 2.7534E+00, 3.0190E+00, 3.1613E+00, 3.8007E+00},
1023  {/*ka=20*/ 2.3330E+00, 2.3330E+00, 2.3330E+00, 2.3330E+00, 2.3330E+00, 2.3330E+00, 2.3330E+00,
1024  1.7698E+00, 1.2244E+00, 8.4708E-01, 5.8603E-01, 4.5491E-01, 3.5312E-01, 2.7411E-01,
1025  2.1278E-01, 1.6517E-01, 1.2821E-01, 9.9523E-02, 7.7254E-02, 5.9968E-02, 4.6550E-02,
1026  5.9968E-02, 7.7254E-02, 9.9523E-02, 1.2821E-01, 1.6517E-01, 2.1278E-01, 2.7411E-01,
1027  3.5312E-01, 4.5491E-01, 5.8603E-01, 8.4708E-01, 1.2244E+00, 1.7698E+00, 2.3330E+00,
1028  2.3330E+00, 2.3330E+00, 2.3330E+00, 2.3330E+00, 2.3330E+00, 2.3330E+00}};
1029 
1031 {
1032  Spectrum directivity_spectrum;
1033  Spectrum spectre_Ka = atmosphere->get_k().mult(support_size); // 1/2 longueur de la diagonale de la bouche
1034 
1035  double theta =
1036  direction.angle(support_normal); // Angle du segment par rapport a la normale au support de la source
1037 
1038  // Angle compris entre 0 et 2pi;
1039  if (theta < 0)
1040  {
1041  theta = theta + M_2PI;
1042  }
1043  if (theta > M_2PI)
1044  {
1045  theta = theta - M_2PI;
1046  }
1047 
1048  int indice_theta = (int)(20.0 * theta / M_PI);
1049 
1050  indice_theta =
1051  indice_theta > (NB_THETA - 2) ? NB_THETA - 2 : indice_theta; // Eviter les depassement de tableau
1052 
1053  for (unsigned int i = 0; i < directivity_spectrum.getNbValues(); i++)
1054  {
1055  double ka = spectre_Ka.getTabValReel()[i];
1056  ka = ka > 20.0 ? 20.0 : ka;
1057 
1058  int indice_Ka = find_Ka_idx(ka);
1059 
1060  directivity_spectrum.getTabValReel()[i] = compute_q(indice_Ka, indice_theta, ka, theta);
1061  }
1062 
1063  return directivity_spectrum;
1064 }
1065 
1066 double BaffledFaceDirectivity::compute_q(int indice_Ka, int indice_theta, double ka, double theta)
1067 {
1068  double tabQ1_1 = _tabQ[indice_Ka][indice_theta];
1069  double tabQ1_2 = _tabQ[indice_Ka][indice_theta + 1];
1070  double tabQ2_1 = _tabQ[indice_Ka + 1][indice_theta];
1071  double tabQ2_2 = _tabQ[indice_Ka + 1][indice_theta + 1];
1072 
1073  double ka1 = _tabKa[indice_Ka];
1074  double ka2 = _tabKa[indice_Ka + 1];
1075 
1076  double theta1 = indice_theta * M_PI / 20;
1077  double theta2 = (indice_theta + 1) * M_PI / 20;
1078 
1079  double val1 = tabQ1_1 + (theta - theta1) * (tabQ1_2 - tabQ1_1) / (theta2 - theta1);
1080  double val2 = tabQ2_1 + (theta - theta1) * (tabQ2_2 - tabQ2_1) / (theta2 - theta1);
1081 
1082  return val1 + (ka - ka1) * (val2 - val1) / (ka2 - ka1);
1083 }
1084 
1086 {
1087  int indice = 0;
1088 
1089  while ((_tabKa[indice] < ka) && (indice < (NB_KA - 1)))
1090  {
1091  indice++;
1092  }
1093 
1094  return indice > (NB_KA - 2) ? NB_KA - 2 : indice - 1; // Eviter les depassement de tableau
1095  // return indice > 0 ? indice - 1 : 0;
1096 }
1097 //
1098 // --------------------------
1099 //
1100 AcousticSource::AcousticSource(const Point& position_, const Spectrum& spectrum_,
1101  SourceDirectivityInterface* directivity_)
1102  : position(position_), spectrum(spectrum_), directivity(directivity_)
1103 {
1104 }
1105 
1106 // ---------
1107 
1108 AcousticReceptor::AcousticReceptor(const Point& position_) : position(position_) {}
1109 
1111 {
1112  Point centroid;
1113  double cumul_x = 0., cumul_y = 0., cumul_z = 0., cumul_level = 0.;
1114  std::deque<double> tabLevels;
1115 
1116  for (unsigned int i = 0; i < tabSources_.size(); i++)
1117  {
1118  tabLevels.push_back(::pow(10, tabSources_[i].spectrum.valGlobDBA() / 10));
1119  }
1120 
1121  for (unsigned int i = 0; i < tabSources_.size(); i++)
1122  {
1123  cumul_x = cumul_x + tabSources_[i].position._x * tabLevels[i];
1124  cumul_y = cumul_y + tabSources_[i].position._y * tabLevels[i];
1125  cumul_z = cumul_z + tabSources_[i].position._z * tabLevels[i];
1126  cumul_level = cumul_level + tabLevels[i];
1127  }
1128 
1129  centroid._x = cumul_x / cumul_level;
1130  centroid._y = cumul_y / cumul_level;
1131  centroid._z = cumul_z / cumul_level;
1132 
1133  return centroid;
1134 }
1135 } /* namespace tympan */
#define M_2PI
2Pi.
Definition: 3d.h:55
double ABS(double a)
Return the absolute value.
Definition: 3d.h:67
CGAL::Exact_predicates_inexact_constructions_kernel K
const char * name
const std::vector< double > tabFreq
Class for the definition of atmospheric conditions.
const OSpectre & get_k() const
Get the wave number spectrum.
double _y
y coordinate of OCoord3D
Definition: 3d.h:283
double _z
z coordinate of OCoord3D
Definition: 3d.h:284
double _x
x coordinate of OCoord3D
Definition: 3d.h:282
The 3D point class.
Definition: 3d.h:487
OSpectreAbstract & sum(const OSpectreAbstract &spectre) const
Arithmetic sum of two spectrums in one-third Octave.
Definition: spectre.cpp:224
OSpectreAbstract & exp(const double coef=1.0)
Compute e^(coef * spectre) of this spectrum.
Definition: spectre.cpp:454
unsigned int getNbValues() const
Number of values in the spectrum.
Definition: spectre.cpp:187
void setType(TYSpectreType type)
Set the spectrum type.
Definition: spectre.h:153
OSpectreAbstract & mult(const OSpectreAbstract &spectre) const
Multiplication of two spectrums.
Definition: spectre.cpp:248
OSpectreComplex toModulePhase() const
Conversion to module/phase.
Definition: spectre.cpp:1399
double * getTabValImag()
Get an array of the imaginary values of the spectrum.
Definition: spectre.h:514
double * getTabValReel() override
Definition: spectre.h:357
static OTabFreq getTabFreqExact()
Definition: spectre.cpp:993
The 3D vector class.
Definition: 3d.h:298
double angle(const OVector3D &vector) const
Computes the angle between this vector and another vector.
Definition: 3d.cpp:243
AcousticBuildingMaterial(const string &name_, const ComplexSpectrum &spectrum)
Constructor.
Definition: entities.cpp:38
ComplexSpectrum asEyring() const
Returns a spectrum with Eyring formulae.
Definition: entities.cpp:43
ComplexSpectrum spectrum
Spectrum to store acoustic values at different frequencies.
Definition: entities.hpp:82
double get_ISO9613_G()
Absorption given by ISO9613.
Definition: entities.cpp:90
void sgn_G_computation(const ComplexSpectrum &localW, ComplexSpectrum &G)
Definition: entities.cpp:366
void computeW(double angle, double length, const ComplexSpectrum &Zs, ComplexSpectrum &W)
Compute numeric distance.
Definition: entities.cpp:267
void computeZs(double angle, ComplexSpectrum Z, ComplexSpectrum &spectrum)
Compute specific impedance.
Definition: entities.cpp:130
TYComplex erfcCas1(const TYComplex &wValue) const
: Functions used in Fw computation
Definition: entities.cpp:428
void computeZc()
Compute characteristic impedance.
Definition: entities.cpp:95
static AtmosphericConditions * atmosphere
Pointer to current atmosphere.
Definition: entities.hpp:162
void limit_W_values(ComplexSpectrum &localW)
Definition: entities.cpp:318
ComplexSpectrum Zf
Effective impedance.
Definition: entities.hpp:195
double trapz(std::vector< double > u, std::vector< double > integrande)
Definition: entities.cpp:241
double gaussianSpectrum(double const k, double const sigma, double const lc)
Definition: entities.cpp:236
TYComplex erfcCas2(const TYComplex &wValue) const
Definition: entities.cpp:497
AcousticGroundMaterial(const string &name_, double resistivity_, double deviation_, double length_, double factor_g_)
Constructor.
Definition: entities.cpp:51
virtual ComplexSpectrum get_absorption(double incidence_angle, double length)
Get material absorption at reflection point.
Definition: entities.cpp:74
void computeK()
Compute wave number.
Definition: entities.cpp:111
ComplexSpectrum Zc
Characteristic impedance.
Definition: entities.hpp:193
TYComplex erfcCas3(const TYComplex &wValue) const
Definition: entities.cpp:508
TYComplex sgnReIm(const TYComplex &W, const TYComplex &G) const
: function used in G computation
Definition: entities.cpp:519
void computeFw(ComplexSpectrum localW, ComplexSpectrum &Fw)
Compute function of numeric distance.
Definition: entities.cpp:290
void erfc_G_computation(const ComplexSpectrum &localW, ComplexSpectrum &G)
Definition: entities.cpp:337
void computeZf(double angle, ComplexSpectrum Zs)
Compute effective impedance in rough ground.
Definition: entities.cpp:153
void computeRp(double angle, const ComplexSpectrum &Zs, ComplexSpectrum &Rp)
Compute reflection coefficient for plane waves.
Definition: entities.cpp:250
void computeQ(double angle, ComplexSpectrum &Rp, ComplexSpectrum &Fw, ComplexSpectrum &Q)
Compute reflection coefficient.
Definition: entities.cpp:411
bool compare(const string &name, double resistivity, double deviation, double length, double factor_g)
Compare this AcousticGroundMaterial to another one.
Definition: entities.cpp:65
Base class for material.
Definition: entities.hpp:37
string name
Material name.
Definition: entities.hpp:50
AcousticMaterialBase(const string &name_)
Constructor.
Definition: entities.cpp:33
AcousticReceptor(const Point &position_)
Constructor to build a receptor defined by the its position.
Definition: entities.cpp:1108
AcousticSource(const Point &point_, const Spectrum &spectrum_, SourceDirectivityInterface *directivity)
Constructor to build a source defined by a point, spectrum, directivity.
Definition: entities.cpp:1100
static const double _tabKa[NB_KA]
Definition: entities.hpp:370
virtual Spectrum lwAdjustment(Vector direction, double distance)
Directivity of a baffled face source.
Definition: entities.cpp:1030
double compute_q(int indice_Ka, int indice_theta, double ka, double theta)
Definition: entities.cpp:1066
static const double _tabQ[NB_KA][NB_THETA]
Definition: entities.hpp:369
virtual Spectrum lwAdjustment(Vector direction, double distance)
Directivity of a chimney face source.
Definition: entities.cpp:754
static const double _tabQ[NB_KA][NB_THETA]
Definition: entities.hpp:332
double compute_q(int ka_idx, int theta_idx, double ka, double theta)
Definition: entities.cpp:787
static AtmosphericConditions * atmosphere
Characteristic size of support face.
Definition: entities.hpp:274
double support_size
Normal of support face.
Definition: entities.hpp:272
Interface for source directivity classes (SphericalSourceDirectivity, CommonFaceDirectivity,...
Definition: entities.hpp:223
double calculC(double distance)
Compute directivity factor.
Definition: entities.cpp:540
virtual Spectrum lwAdjustment(Vector direction, double distance)
Directivity of a volume face.
Definition: entities.cpp:563
static const double _tabRA[]
RA form factor.
Definition: entities.hpp:293
static const double _tabCor[]
Correction factors.
Definition: entities.hpp:294
#define M_PI
Pi.
Definition: color.cpp:25
#define NB_KA
Definition: entities.cpp:819
#define NB_THETA
Definition: entities.cpp:827
This file provides the declaration of the entities of the model, which inherit from BaseEntity.
std::complex< double > TYComplex
Definition: macros.h:25
TYComplex cotanh(const TYComplex &valeur)
Definition: macros.h:34
#define CPLX_UN
Definition: macros.h:27
#define CPLX_J
Definition: macros.h:29
#define CPLX_MUN
Definition: macros.h:28
std::deque< AcousticSource > source_pool_t
Array of sources.
Definition: entities.hpp:395
Point ComputeAcousticCentroid(const source_pool_t &tabSources_)
Definition: entities.cpp:1110
std::vector< double > OTabFreq
Frequencies collection.
Definition: spectre.h:60
@ SPECTRE_TYPE_AUTRE
Definition: spectre.h:32
@ SPECTRE_TYPE_ABSO
Definition: spectre.h:29