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