Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYAcousticModel9613Solver.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 
16 #include <deque>
17 #include <list>
18 #include <cmath>
19 #include <algorithm>
20 #include "Tympan/core/defines.h"
25 #include "TYSolver9613Solver.h"
26 #include "TYSolverHelper.h"
27 
29 
31  : TYAcousticModel(), _solver(solver)
32 {
34  _absoNulle.setType(SPECTRE_TYPE_ABSO); // Spectre d'absorption
35 }
36 
38 {
39  // Compute wave length
40  double c_9613_2 = 340.0;
42 }
43 
44 void TYAcousticModel9613Solver::compute(const std::deque<TYSIntersection>& tabIntersect,
45  TYTrajet9613Solver& trajet, TabPoint3D& ptsTop, TabPoint3D& ptsLeft,
46  TabPoint3D& ptsRight)
47 {
48  bool vertical = true, horizontal = false;
49  bool left = true, right = false;
50 
51  // Construction du rayon SR
52  OSegment3D rayon;
53  trajet.getPtSetPtRfromOSeg3D(rayon);
54  bool conditionFav = false;
55 
56  // Calcul des conditions de propagation suivant la direction du vent
58  assert(config->DSWindDirection >= 0 && config->DSWindDirection <= 360);
59 
60  double windRadian = DEGTORAD(config->DSWindDirection);
61  OVector3D windDirection = OVector3D(-sin(windRadian), -cos(windRadian), 0);
62  OVector3D propaDirection = rayon.toVector3D();
63  propaDirection._z = 0;
64  double angle =
65  RADTODEG(acos(windDirection.dot(propaDirection) /
66  (windDirection.norme() * propaDirection.norme()))); // Angle always between 0-180
67  assert(180 >= angle >= 0);
68  assert(180 >= config->AngleFavorable >= 0);
69 
70  if (angle <= config->AngleFavorable)
71  {
72  conditionFav = true;
73  }
74  else
75  {
76  conditionFav = false;
77  }
78 
79  // Recuperation de la source
80  tympan::AcousticSource& source = trajet.asrc;
81 
82  // Distance de la source au recepteur
83  double distance = trajet.getDistance();
84 
85  TYTabChemin9613Solver& tabChemins = trajet.getChemins();
86 
87  // Calcul du chemin direct
88  computeCheminSansEcran(tabIntersect, rayon, source, tabChemins, distance, conditionFav);
89 
90  if (ptsTop.size() > 1 || ptsLeft.size() > 1 || ptsRight.size() > 1)
91  {
92  // Calcul des parcours lateraux
93  // 1. Vertical
94  computeCheminsAvecEcran(rayon, source, ptsTop, vertical, tabChemins, distance, right);
95 
96  // 2. Horizontal gauche
97  computeCheminsAvecEcran(rayon, source, ptsLeft, horizontal, tabChemins, distance, left);
98 
99  // 3. Horizontal droite
100  computeCheminsAvecEcran(rayon, source, ptsRight, horizontal, tabChemins, distance, right);
101  }
102 
103  // Calcul des reflexions si necessaire
104  computeCheminReflexion(tabIntersect, rayon, source, tabChemins, distance);
105 
106  // Calcul la pression cumulee de tous les chemins au point de reception du trajet
107  solve(trajet);
108 
109  // Le calcul est fini pour ce trajet, on peut effacer les tableaux des chemins
110  tabChemins.clear();
111 }
112 
114  const tympan::AcousticSource& source,
115  const TabPoint3D& pts, const bool vertical,
116  TYTabChemin9613Solver& tabPaths, double distance,
117  const bool left) const
118 {
119  /* ============================================================================================================
120  In 9613, no reflexion on the ground is computed
121  ==============================================================================================================*/
122  if (pts.size() <= 1)
123  {
124  tabPaths[0].setAttenuationBarWhenNoPath(vertical, left);
125  return false;
126  }
127 
128  double dss{0.0}; // Length between source and first edge of diffraction
129  double dsr{0.0}; // Length between last edge of diffraction and receptor
130 
131  OPoint3D firstPt(pts[1]);
132  OPoint3D lastPt(pts[pts.size() - 1]);
133 
134  TYTabEtape9613Solver tabSteps;
135  double pathLength = 0.0;
136 
137  /*--- BEFORE OBSTACLE ---*/
138 
139  TYTabEtape9613Solver steps;
140  OSegment3D curSegment(ray._ptA, firstPt);
141  double tempLength = curSegment.longueur();
142 
143  bool bPathOk = addGroundSteps(ray._ptA, firstPt, source, true, steps); // Add step before obstacle
144 
145  // If a problem has occurred, stop path creation
146  if (!bPathOk)
147  {
148  return true;
149  }
150 
151  tabSteps.push_back(steps[0]); // Add source step to table of steps
152  pathLength += tempLength;
153  dss = tempLength;
154 
155  steps.clear(); // Clear steps content
156 
157  /*--- BYPASS OF THE OBSTACLE ---*/
158 
159  double width = 0.0;
160  TYEtape9613Solver step;
161 
162  for (unsigned int i = 1; i < pts.size() - 1; i++)
163  {
164  width += (OSegment3D(pts[i], pts[i + 1])).longueur();
165 
166  step._pt = pts[i];
167  step._type = TYDIFFRACTION;
168  step._Absorption = _absoNulle;
169 
170  tabSteps.push_back(step);
171  }
172 
173  pathLength += width;
174 
175  /*--- AFTER OBSTACLE ---*/
176  curSegment = OSegment3D(lastPt, ray._ptB);
177  tempLength = curSegment.longueur();
178 
179  addGroundSteps(lastPt, ray._ptB, source, false, steps);
180 
181  tabSteps.push_back(steps[0]);
182  pathLength += tempLength;
183  dsr = tempLength;
184 
185  steps.clear();
186 
187  /*--- COMPUTE SCREEN EFFECT ATTENUATION ON THE CURRENT PATH ---*/
188 
189  OSpectreOctave Dz;
190 
191  step._pt = ray._ptB;
192  step._type = TYRECEPTEUR;
193  step._Absorption = _absoNulle;
194 
195  Dz = calculAttDiffraction(ray, pathLength, dss, dsr, width, vertical);
196  step._Attenuation = Dz;
197  tabSteps.push_back(step);
198 
199  /*--- ADD PATH TO the table of paths ---*/
200 
201  TYChemin9613Solver path;
203  path.setDistance(distance);
204  path.setLongueur(pathLength);
205 
206  tabPaths.push_back(path);
207 
208  // Compute barrier attenuation
209  tabPaths[0].computeBarAttenuation(Dz, vertical, left);
210 
211  // Build equivalent path for rays
212  path.build_eq_path(tabSteps);
213 
214  tabSteps.clear();
215  steps.clear();
216 
217  return true;
218 }
219 
221  const tympan::AcousticSource& source, const bool& fromSource,
222  TYTabEtape9613Solver& steps) const
223 {
224  bool res = true;
225 
226  TYEtape9613Solver curStep;
227 
228  // === BUILD DIRECT TRIP ptStart-ptEnd
229  curStep._pt = ptStart;
230 
231  if (fromSource) // If we start from source, its directivity is considered
232  {
233  curStep._type = TYSOURCE;
234  curStep._Absorption =
235  source.directivity->lwAdjustment(OVector3D(ptStart, ptEnd), ptStart.distFrom(ptEnd));
236  }
237  else
238  {
239  curStep._type = TYDIFFRACTION;
240  curStep._Absorption = _absoNulle;
241  }
242 
243  steps.push_back(curStep);
244 
245  return res;
246 }
247 
248 void TYAcousticModel9613Solver::computeCheminSansEcran(const std::deque<TYSIntersection>& tabIntersect,
249  const OSegment3D& ray,
250  const tympan::AcousticSource& source,
251  TYTabChemin9613Solver& TabChemin, double distance,
252  bool conditionFav) const
253 {
254  /*
255  COMPUTATION FOR A ROUTE WITHOUT OBSTACLE CONSISTS OF ONE DIRECT PATH
256  */
257  // Add direct path
258  std::unique_ptr<TYChemin9613Solver> chemin = createChemin();
259 
260  // Compute mean slope on source-receptor route
261  OSegment3D segMeanSlope;
262  meanSlope(ray, segMeanSlope);
263 
264  OPoint3D S2D{ray._ptA._x, ray._ptA._y, 0.0};
265  OPoint3D R2D{ray._ptB._x, ray._ptB._y, 0.0};
266  OSegment3D SR2D{S2D, R2D};
267  double dp = SR2D.longueur();
268 
269  TYTabEtape9613Solver Etapes;
270  double Gs{0.0}, Gm{0.0}, Gr{0.0};
271  double hs{0.0}, hr{0.0};
272 
273  computeSegmentEdgesHeights(hs, hr, segMeanSlope, ray);
274 
275  addGroundSteps(ray._ptA, ray._ptB, source, true, Etapes);
276  getGroundfactors(tabIntersect, SR2D, hs, hr, Gs, Gm, Gr);
277 
278  // Add direct path
279  chemin->setType(TYTypeChemin::CHEMIN_DIRECT);
280  TYTabEtape9613Solver tabEtapes;
281  tabEtapes.push_back(Etapes[0]); // Add direct step
282  chemin->setLongueur(distance); // In this case, length = source/receptor distance
283  chemin->setDistance(distance);
284  chemin->calcAttenuation(tabEtapes, *_pSolverAtmos, dp, hs, hr, Gs, Gm, Gr);
285  TabChemin.push_back(*chemin); // Add path in array of paths
286 
287  tabEtapes.clear(); // Empty array of steps
288 }
289 
290 bool TYAcousticModel9613Solver::getGroundfactors(const std::deque<TYSIntersection>& tabIntersect,
291  const OSegment3D& ray2D, double hs, double hr, double& Gs,
292  double& Gm, double& Gr) const
293 {
294  double heightRatio = 30.0;
295 
296  bool res = true;
297 
298  // === CONSTRUCTION OF DIRECT ROUTE ABOVE HORIZONTAL PLANE
299  OPoint3D ptStartProj = ray2D._ptA; // PtDebut projected on horizontal plane
300  OPoint3D ptEndProj = ray2D._ptB; // PtFin projected on horizontal plane
301 
302  // === COMPUTE SOURCE, MIDDLE AND RECEPTOR ZONES
303  OVector3D SR{ray2D._ptA, ray2D._ptB};
304  double dp = SR.norme(); // Distance in meter, between source and receptor, projected on ground plan
305  SR.normalize();
306  OPoint3D ptGSrcZone;
307  OPoint3D ptGRcpZone;
308  OPoint3D ptGMidZone;
309 
310  // Source zone must not exceed receptor
311  if (heightRatio * hs < dp)
312  {
313  ptGSrcZone = ptStartProj + SR * heightRatio * hs;
314  }
315  else
316  {
317  ptGSrcZone = ptStartProj + SR * dp;
318  }
319 
320  // Receptor zone must not exceed source
321  if (heightRatio * hr < dp)
322  {
323  ptGRcpZone = ptEndProj + (-1.0) * SR * heightRatio * hr;
324  }
325  else
326  {
327  ptGRcpZone = ptEndProj + (-1.0) * SR * dp;
328  }
329 
330  // === COMPUTE GROUND FACTOR FOR EACH ZONE
331  double GZone{0.0}, dpZone{0.0};
332  computeGZone(ptStartProj, ptGSrcZone, GZone, dpZone, tabIntersect);
333  if (dpZone != 0.0)
334  {
335  Gs = GZone / dpZone;
336  }
337  else
338  {
339  Gs = 0.5;
340  }
341  computeGZone(ptGRcpZone, ptEndProj, GZone, dpZone, tabIntersect);
342  if (dpZone != 0.0)
343  {
344  Gr = GZone / dpZone;
345  }
346  else
347  {
348  Gr = 0.5;
349  }
350  computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersect);
351  if (dpZone != 0.0)
352  {
353  Gm = GZone / dpZone;
354  }
355  else
356  {
357  Gm = 0.5;
358  }
359 
360  return res;
361 }
362 
363 bool TYAcousticModel9613Solver::getGroundfactors(const std::deque<TYSIntersection>& tabIntersectUpSegment,
364  const std::deque<TYSIntersection>& tabIntersectDownSegment,
365  const OSegment3D& SO2D, const OSegment3D& OR2D, double hs,
366  double hr, double& Gs, double& Gm, double& Gr) const
367 {
368  double heightRatio = 30.0;
369  bool res = true;
370 
371  // Construction of points from segments parameters
372  OPoint3D ptSrc2D = SO2D._ptA;
373  OPoint3D ptO2D = SO2D._ptB;
374  OPoint3D ptRcp2D = OR2D._ptB;
375 
376  // Computation of 2D distance and construction of unit vectors
377  OVector3D SO{SO2D._ptA, SO2D._ptB};
378  double dpSO =
379  SO.norme(); // Distance in meter, between source and reflexion point, projected on ground plan
380  SO.normalize();
381 
382  OVector3D OR{OR2D._ptA, OR2D._ptB};
383  double dpOR =
384  OR.norme(); // Distance in meter, between reflexion point and receptor, projected on ground plan
385  OR.normalize();
386 
387  double dp = dpSO + dpOR; // Distance in meter, between source and receptor, projected on ground plan
388 
389  // === COMPUTE GROUND FACTOR FOR EACH ZONE
390  OPoint3D ptGSrcZone;
391  OPoint3D ptGRcpZone;
392  OPoint3D ptGMidZone;
393 
394  bool bPtGSrcZoneInSO{false}; // True if ptGSrcZone in [SO] segment
395  bool bPtGRcpZoneInOR{false}; // True if ptGRcpZone in [OR] segment
396 
397  // == COMPUTE GROUND FACTOR FOR SOURCE ZONE
398  if (heightRatio * hs < dpSO)
399  {
400  // ptGSrcZone belongs to [SO]
401  bPtGSrcZoneInSO = true;
402  ptGSrcZone = ptSrc2D + (SO)*heightRatio * hs;
403  }
404  else if (heightRatio * hs < dp)
405  {
406  // ptGSrcZone belongs to [OR]
407  ptGSrcZone = ptO2D + (OR) * (heightRatio * hs - dpSO);
408  }
409  else
410  { // Source Zone must not exceed receptor
411  ptGSrcZone = ptO2D + (OR)*dpOR;
412  }
413 
414  // Compute Gs
415  double GZone{0.0}, dpZone{0.0};
416  if (bPtGSrcZoneInSO)
417  {
418  computeGZone(ptSrc2D, ptGSrcZone, GZone, dpZone, tabIntersectUpSegment);
419  }
420  else
421  {
422  double Gs1{0.0}, dp1{0.0}, Gs2{0.0}, dpOGs{0.0};
423  computeGZone(ptSrc2D, ptO2D, Gs1, dp1, tabIntersectUpSegment); // Gs1 = G(Src2D->ptO2D) / dpSO
424  computeGZone(ptO2D, ptGSrcZone, Gs2, dpOGs, tabIntersectDownSegment); // Gs2 = G(ptO2D->Gs2D) / dpOGs
425  GZone = Gs1 + Gs2;
426  dpZone = dp1 + dpOGs;
427  }
428 
429  if (dpZone != 0)
430  {
431  Gs = GZone / dpZone;
432  }
433  else
434  {
435  Gs = 0.5;
436  }
437 
438  // == COMPUTE GROUND FACTOR FOR RECEPTOR ZONE
439  if (heightRatio * hr < dpOR)
440  {
441  // ptGRcpZone belongs to [OR]
442  bPtGRcpZoneInOR = true;
443  ptGRcpZone = ptRcp2D + (-1.0) * OR * heightRatio * hr;
444  }
445  else if (heightRatio * hr < dp)
446  {
447  // ptGSrcZone belongs to [SO]
448  ptGRcpZone = ptO2D + (-1.0) * SO * (heightRatio * hr - dpOR);
449  }
450  else
451  { // Source Zone must not exceed receptor
452  ptGRcpZone = ptO2D + (-1.0) * SO * dpSO;
453  }
454 
455  // Compute Gr
456  dpZone = 0.0;
457  if (bPtGRcpZoneInOR)
458  {
459  computeGZone(ptGRcpZone, ptRcp2D, GZone, dpZone, tabIntersectDownSegment);
460  }
461  else
462  {
463  double Gr1{0.0}, dp2{0.0}, Gr2{0.0}, dpGrO{0.0};
464  computeGZone(ptGRcpZone, ptO2D, Gr1, dpGrO, tabIntersectUpSegment); // Gr1 = G(Gr2D->ptO2D) / dpGrO
465  computeGZone(ptO2D, ptRcp2D, Gr2, dp2, tabIntersectDownSegment); // Gr2 = G(ptO2D->ptRcp2D) / dpOR
466 
467  GZone = Gr1 + Gr2;
468  dpZone = dpGrO + dp2;
469  }
470 
471  if (dpZone != 0)
472  {
473  Gr = GZone / dpZone;
474  }
475  else
476  {
477  Gr = 0.5;
478  }
479 
480  // == COMPUTE GROUND FACTOR FOR MIDDLE ZONE
481  // If GSrc and GRcp belong to [SO]
482  if (bPtGSrcZoneInSO && !bPtGRcpZoneInOR)
483  {
484  computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectUpSegment);
485  }
486  // Else, if GSrc and GRcp belong to [OR]
487  else if (!bPtGSrcZoneInSO && bPtGRcpZoneInOR)
488  {
489  computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectDownSegment);
490  }
491  // Else, if GSrc belongs to [SO], therefore GRcp belongs to [OR]
492  else if (bPtGSrcZoneInSO)
493  {
494  double Gm1{0.0}, dpm1{0.0}, Gm2{0.0}, dpm2{0.0};
495  computeGZone(ptGSrcZone, ptO2D, Gm1, dpm1, tabIntersectUpSegment);
496  computeGZone(ptO2D, ptGRcpZone, Gm2, dpm2, tabIntersectDownSegment);
497  GZone = Gm1 + Gm2;
498  dpZone = dpm1 + dpm2;
499  }
500  // Else if GSrc belongs to [OR], therefore GRcp belongs to [SO]
501  else
502  {
503  double Gm1{0.0}, dpm1{0.0}, Gm2{0.0}, dpm2{0.0};
504  computeGZone(ptGRcpZone, ptO2D, Gm1, dpm1, tabIntersectUpSegment);
505  computeGZone(ptO2D, ptGSrcZone, Gm2, dpm2, tabIntersectDownSegment);
506  GZone = Gm1 + Gm2;
507  dpZone = dpm1 + dpm2;
508  }
509 
510  if (dpZone != 0)
511  {
512  Gm = GZone / dpZone;
513  }
514  else
515  {
516  Gm = 0.5;
517  }
518 
519  return res;
520 }
521 
523  const OSpectreOctave& Abar_left,
524  const OSpectreOctave& Abar_right)
525 {
526  OSpectreOctave Abar;
527  for (unsigned int i = 0; i < TY_SPECTRE_OCT_NB_ELMT; i++)
528  {
529  Abar.getTabValReel()[i] = -10 * log10(pow(10, -0.1 * Abar_top.getTabValReel()[i]) +
530  pow(10, -0.1 * Abar_left.getTabValReel()[i]) +
531  pow(10, -0.1 * Abar_right.getTabValReel()[i]));
532  if (Abar.getTabValReel()[i] < 0)
533  {
534  Abar.getTabValReel()[i] = 0;
535  }
536  }
537  return Abar;
538 }
539 
540 bool TYAcousticModel9613Solver::computeGZone(const OPoint3D& ptDebut, const OPoint3D& ptFin, double& GZone,
541  double& dpZone,
542  const std::deque<TYSIntersection>& tabIntersect) const
543 {
544  bool ret = true;
545  OSegment3D segZone(ptDebut, ptFin);
546  OVector3D DF(ptDebut, ptFin);
547  std::unordered_map<OVector3D, double, OVector3DHash> mapResultSegFactorG;
548 
549  // Loop on intersections of Topography triangles with EV plane.
550  // For each triangle, we search the intersection between the intersecting segment and the zone segment.
551  // The intersecting segment has an homogeneous ground factor G.
552  // It is used to compute a balanced ground factor over the zone segment.
553  size_t nbTriangles = tabIntersect.size();
554  double currentG = 0.0;
555  GZone = 0.0;
556  dpZone = 0.0;
557 
558  // Edges of current intersecting segment
559  OPoint3D ptDebutResult;
560  OPoint3D ptFinResult;
561 
562  for (unsigned int i = 0; i < nbTriangles; i++)
563  {
564  TYSIntersection inter = tabIntersect[i];
565 
566  // If triangle is not topography or does not intersect EV plane, then continue with following triangle
567  if ((inter.isInfra) || !(inter.bIntersect[0]))
568  {
569  continue;
570  }
571 
572  OSegment3D currentSeg = tabIntersect[i].segInter[0];
573  currentG = tabIntersect[i].material->get_ISO9613_G();
574 
575  // We build AB segment the projection of the topography segment on the horizontal plane
576  OPoint3D ptDebutCurrentProj{currentSeg._ptA._x, currentSeg._ptA._y, 0.0};
577  OPoint3D ptFinCurrentProj{currentSeg._ptB._x, currentSeg._ptB._y, 0.0};
578 
579  OSegment3D segAB{ptDebutCurrentProj, ptFinCurrentProj};
580  OVector3D AB{ptDebutCurrentProj, ptFinCurrentProj};
581  // Orientate AB segment as zone segment DF
582  if (AB.scalar(DF) <= 0)
583  {
584  segAB = segAB.swap();
585  }
586  OVector3D AD(segAB._ptA, segZone._ptA);
587  OVector3D AF(segAB._ptA, segZone._ptB);
588  OVector3D BD(segAB._ptB, segZone._ptA);
589  OVector3D BF(segAB._ptB, segZone._ptB);
590 
591  bool intersect = true;
592 
593  // If A belongs to zone segment DF
594  if (AD.scalar(AF) <= 0)
595  {
596  // then A is the starting edge of the intersecting segment
597  ptDebutResult = segAB._ptA;
598 
599  // If B belongs to zone segment DF
600  if (BD.scalar(BF) <= 0)
601  {
602  // then B is the ending edge of the intersecting segment
603  ptFinResult = segAB._ptB;
604  }
605  else
606  // else F is the ending edge of the intersecting segment
607  {
608  ptFinResult = segZone._ptB;
609  }
610  }
611  else
612  {
613  // Else A does not belong to zone segment DF
614  // If B does not belong to zone segment either
615  if (BD.scalar(BF) >= 0)
616  {
617  // and if A and B are from each side of zone segment
618  if (AD.scalar(BF) <= 0)
619  {
620  // then intersecting segment is the zone segment DF itself
621  ptDebutResult = segZone._ptA;
622  ptFinResult = segZone._ptB;
623  }
624  else
625  {
626  // Else A and B are on the same side of segment zone, so no intersection
627  intersect = false;
628  }
629  }
630  else
631  // Else B belong to segment zone DF but not A
632  {
633  ptDebutResult = segZone._ptA;
634  ptFinResult = segAB._ptB;
635  }
636  }
637 
638  if (intersect)
639  {
640  OVector3D result{ptDebutResult, ptFinResult};
641  auto it = mapResultSegFactorG.find(result);
642  if (it != mapResultSegFactorG.end())
643  {
644  GZone = GZone + 0.5 * result.norme() * (currentG - it->second);
645  }
646  else
647  {
648  GZone = GZone + result.norme() * currentG;
649  dpZone += result.norme();
650  }
651  mapResultSegFactorG[result] = currentG;
652  }
653  }
654 
655  return ret;
656 }
657 
658 void TYAcousticModel9613Solver::computeCheminReflexion(const std::deque<TYSIntersection>& tabIntersect,
659  const OSegment3D& ray,
660  const tympan::AcousticSource& source,
661  TYTabChemin9613Solver& TabChemins,
662  double distance) const
663 {
664  if (!_useReflex)
665  {
666  return;
667  }
668 
669  OSegment3D segInter;
670  OSegment3D rayonTmp;
671  OPoint3D ptSym;
672  OSpectreOctave SpectreAbso;
673 
674  OSegment3D seg; // Image source -> receptor segment
675  OSegment3D upwardSeg; // Source -> reflexion point segment
676  OSegment3D downwardSeg; // Reflexion point -> receptor segment
677 
678  OPoint3D pt; // Intersection (reflexion) point
679 
680  size_t nbFaces = tabIntersect.size();
681 
682  // For each face test reflexion
683  for (unsigned int i = 0; i < nbFaces; i++)
684  {
685  TYSIntersection inter = tabIntersect[i];
686 
687  // If face cannot interact skip it
688  if ((!inter.isInfra) || !(inter.bIntersect[1]))
689  {
690  continue;
691  }
692 
693  segInter = inter.segInter[1];
694 
695  // Compute symmetric of A with respect to the segment
696  segInter.symetrieOf(ray._ptA, ptSym); // We don't deal with this function return value
697  seg._ptA = ptSym;
698  seg._ptB = ray._ptB; // Image source -> receptor segment
699 
700  if (segInter.intersects(seg, pt, TYSEUILCONFONDUS))
701  {
702  // Construction of reflexion point -> source segment
703  upwardSeg._ptA = ray._ptA;
704  upwardSeg._ptB = pt;
705  // Construction of reflexion point -> receptor segment
706  downwardSeg._ptA = upwardSeg._ptB;
707  downwardSeg._ptB = ray._ptB;
708 
709  bool intersect = false;
710  size_t j = 0;
711 
712  // If we cross another face, which can be topography, the reflexion path is not taken into account
713  while ((j < nbFaces) && (!intersect))
714  {
715  if (j == i)
716  {
717  j++;
718  continue; // If face cannot interact skip it
719  }
720 
721  segInter = tabIntersect[j].segInter[1];
722 
723  // We test whether segInter intersects upward segment or
724  // downward segment in global plane.
725  // Point pt is not use, we only care about testing intersection
726  if ((segInter.intersects(upwardSeg, pt, TYSEUILCONFONDUS)) ||
727  (segInter.intersects(downwardSeg, pt, TYSEUILCONFONDUS)))
728  {
729  // Intersection found, exit from the loop
730  intersect = true;
731  break;
732  }
733 
734  j++;
735  }
736 
737  // If reflected path is not intersected, reflexion can be computed
738  if (!intersect)
739  {
740  SpectreAbso = dynamic_cast<tympan::AcousticBuildingMaterial*>(inter.material)->spectrum;
741 
742  TYTabEtape9613Solver tabEtapes;
743 
744  double pathLength = upwardSeg.longueur() + downwardSeg.longueur();
745 
746  TYEtape9613Solver Etape;
747  // First step : from source to reflexion point
748  Etape._pt = ray._ptA;
749  Etape._type = TYSOURCE;
750  Etape._Absorption = source.directivity->lwAdjustment(
751  OVector3D(upwardSeg._ptA, upwardSeg._ptB),
752  upwardSeg.longueur()); // Directivity factor toward receptor image
753 
754  tabEtapes.push_back(Etape);
755 
756  // Second step : from reflexion point to end of ray
757  Etape._pt = downwardSeg._ptA;
758  Etape._type = TYREFLEXION;
759  Etape._Absorption = SpectreAbso;
760 
761  tabEtapes.push_back(Etape);
762 
763  // Compute mean slope on source-receptor route
764  OSegment3D segMeanSlope;
765  meanSlope(ray, segMeanSlope);
766 
767  OPoint3D S2D{upwardSeg._ptA._x, upwardSeg._ptA._y, 0.0};
768  OPoint3D O2D{upwardSeg._ptB._x, upwardSeg._ptB._y, 0.0};
769  OPoint3D R2D{downwardSeg._ptB._x, downwardSeg._ptB._y, 0.0};
770  OSegment3D raySO{S2D, O2D};
771  OSegment3D rayOR{O2D, R2D};
772  double dp = raySO.longueur() + rayOR.longueur();
773 
774  TYTabEtape Etapes;
775  double Gs{0.0}, Gm{0.0}, Gr{0.0};
776  double hs{0.0}, hr{0.0};
777 
778  computeSegmentEdgesHeights(hs, hr, segMeanSlope, ray);
779 
780  // Compute intersecting segments for reflected ray
781  std::deque<TYSIntersection> tabIntersectUpSegment, tabIntersectDownSegment;
782  _solver.selectFaces(tabIntersectUpSegment, upwardSeg, source.volume_id);
783  _solver.selectFaces(tabIntersectDownSegment, downwardSeg, source.volume_id);
784 
785  // Compute ground factors for reflected ray
786  getGroundfactors(tabIntersectUpSegment, tabIntersectDownSegment, raySO, rayOR, hs, hr, Gs, Gm,
787  Gr);
788 
789  std::unique_ptr<TYChemin9613Solver> chemin = createChemin();
790  chemin->setType(TYTypeChemin::CHEMIN_REFLEX);
791  chemin->setLongueur(pathLength);
792  chemin->setDistance(distance);
793  chemin->calcAttenuation(tabEtapes, *_pSolverAtmos, dp, hs, hr, Gs, Gm, Gr);
794 
795  // Compute minimal extension condition
796  // inter.pFaceGeomData is assumed to be valid, by construction of infrastructure elements
797  // a segfault here is a symptom of badly built AcousticProblemModel in _business2solver
798  const OPoint3D& S = upwardSeg._ptA;
799  const OPoint3D& O = upwardSeg._ptB;
800  const OPoint3D& R = downwardSeg._ptB;
801  const double a{inter.pFaceGeomData->a};
802  const double h{inter.pFaceGeomData->h};
803  const OVector3D& normal = inter.pFaceGeomData->n;
804  chemin->calcMinimalExtensionCondition(S, O, R, a, h, normal);
805 
806  TabChemins.push_back(*chemin); // Put the reflected path in paths table
807  tabEtapes.clear();
808  }
809  }
810  }
811 }
812 
814 {
815  // C3 = (1 + (5 * lambda / width)^2) / (1 / 3 + (5 * lambda / width)^2)
816 
818  OSpectreOctave opLambda;
819 
820  if (width < 0.5)
821  {
822  C3.setDefaultValue(1.0);
823  }
824  else
825  {
826  const double oneThird = 1.0 / 3.0;
827 
828  opLambda = _lambda * (5.0 / width); // (5*lambda/e)
829  opLambda = opLambda * opLambda; // (5*lambda/e)^2
830 
831  C3 = opLambda + 1.0; // 1 + (5*lambda/e)^2
832  C3 = C3.div(opLambda + oneThird); // (1 + (5*lambda/e)^2) / (1/3 + (5*lambda/e)^2)
833  }
834 
835  C3.setType(SPECTRE_TYPE_AUTRE); // Neither Attenuation, nor Absorption
836 
837  return C3;
838 }
839 
841  const double& dss, const double& dsr,
842  const double& width,
843  const bool& vertical) const
844 {
845  double rd;
846 
847  OSpectreOctave C3 = calculC3(width); // Corrective factor linked with screen width
848 
849  double C2{20.0};
850  OSpectreOctave zmin = calculZMin(C2, C3);
851 
852  rd = ray.longueur();
853 
854  double z = re - rd; // Path-length difference
855  z = z <= 0 ? 0.0 : z;
856 
857  OSpectreOctave Kmeteo = calculKmeteo(vertical, dss, dsr, rd, z, width, zmin);
858 
859  OSpectreOctave Dz = calculDz(C2, z, C3, Kmeteo, zmin);
860  // If diffraction occurs in vertical plane (horizontal edge)
861  // minimal and amaximal attenuations are limited respectively
862  // to 0 dB and 20 or 25 dB (whether screen is thin or wide).
863  if (vertical)
864  {
865  Dz = limAttDiffraction(Dz, C3);
866  }
867 
868  return Dz;
869 }
870 
872 {
873  // zmin = 0.0
874  OSpectreOctave zmin{0.0};
875  return zmin;
876 }
877 
878 OSpectreOctave TYAcousticModel9613Solver::calculKmeteo(const bool vertical, const double d_SS,
879  const double d_SR, const double d, const double z,
880  const double e, const OSpectreOctave& z_min) const
881 {
882  // K_meteo = exp[-(1 / 2000) * sqrt(d_SS * d_SR * d/(2z))] for z > 0 and vertical diffraction
883  // K_meteo = 1 for z <= 0 or for lateral diffraction
884  double Kmeteo = 1.0;
885  if (z > 0.0 && vertical)
886  {
887  Kmeteo = exp(-(1.0 / 2000.0) * sqrt(d_SS * d_SR * d / (2 * z)));
888  }
889  return OSpectreOctave{Kmeteo};
890 }
891 
892 OSpectreOctave TYAcousticModel9613Solver::calculDz(const double z, const double C2, const OSpectreOctave& C3,
893  const OSpectreOctave& Kmeteo,
894  const OSpectreOctave& zmin) const
895 {
896  // Dz = 10 * log10[3 + (C2 / lambda) * C3 * z * Kmeteo] dB for z > zmin
897  // Dz = 0 dB for z <= zmin
898 
899  OSpectreOctave Dz{0.0};
900 
901  double* dz = Dz.getTabValReel();
902  const double* lambda = _lambda.getTabValReel();
903  const double* c3 = C3.getTabValReel();
904  const double* kmeteo = Kmeteo.getTabValReel();
905  const double* zMin = zmin.getTabValReel();
906 
907  for (std::size_t i = 0; i < TY_SPECTRE_OCT_NB_ELMT; ++i)
908  {
909  if (z > zMin[i])
910  {
911  dz[i] = 10.0 * std::log10(3.0 + (C2 / lambda[i]) * c3[i] * z * kmeteo[i]);
912  }
913  }
914 
915  return Dz;
916 }
917 
919  const OSpectreOctave& C) const
920 {
922 
923  double lim20dB = 20.0;
924  double lim25dB = 25.0;
925  double lim0dB = 0.0;
926 
927  double valeur;
928 
929  for (unsigned int i = 0; i < sNC.getNbValues(); i++)
930  {
931  valeur = sNC.getTabValReel()[i];
932 
933  valeur = valeur < lim0dB ? lim0dB : valeur; // L'attenuation ne peut etre inferieure a 0 dB
934 
935  if ((C.getTabValReel()[i] - 1) <= 1e-2) // Comportement ecran mince
936  {
937  valeur = valeur > lim20dB ? lim20dB : valeur;
938  }
939  else // Comportement ecran epais ou multiple
940  {
941  valeur = valeur > lim25dB ? lim25dB : valeur;
942  }
943 
944  s.getTabValReel()[i] = valeur;
945  }
946 
947  return s;
948 }
949 
951 {
952  // Get results for each path
953 #ifdef _DEBUG
954  std::vector<PathResults> pathsResults;
955 #endif
956  PathResults currentPathResults;
957  // Global sound level pressure
958  OSpectreOctave& SLp = trajet.getSpectreOct();
959  SLp.setType(SPECTRE_TYPE_LP); // Receptor spectrum is a pressure spectrum
961 
962  for (unsigned int i = 0; i < trajet.getNbChemins(); i++)
963  {
964  currentPathResults.path_id = i;
965  currentPathResults.pathType = trajet.getChemin(i).getType();
966  float minSRDistance = config->MinSRDistance;
967  double longueur = (minSRDistance > trajet.getChemin(i).getLongueur())
968  ? minSRDistance
969  : trajet.getChemin(i).getLongueur();
970 
971  // Screen and ground paths results are held by direct path
972  if (currentPathResults.pathType == TYTypeChemin::CHEMIN_ECRAN)
973  {
974  continue;
975  }
976  // Direct Ray computations
978 
979  // Compute attenuations
980  currentPathResults.Adiv = OSpectreOctave(20.0 * log10(longueur) + 11.0);
981  currentPathResults.Aatm = trajet.getChemin(i).getAttenuation(TYTypeAttenuation::ATTENUATION_ATM);
982  currentPathResults.Agr_s = trajet.getChemin(i).getAttenuation(TYTypeAttenuation::ATTENUATION_GND_S);
983  currentPathResults.Agr_r = trajet.getChemin(i).getAttenuation(TYTypeAttenuation::ATTENUATION_GND_R);
984  currentPathResults.Agr_m = trajet.getChemin(i).getAttenuation(TYTypeAttenuation::ATTENUATION_GND_M);
986  currentPathResults.Dz_top = trajet.getChemin(i).getAttenuation(TYTypeAttenuation::DZ_TOP);
987  currentPathResults.Dz_left = trajet.getChemin(i).getAttenuation(TYTypeAttenuation::DZ_LEFT);
988  currentPathResults.Dz_right = trajet.getChemin(i).getAttenuation(TYTypeAttenuation::DZ_RIGHT);
989  currentPathResults.Abar_top =
991  currentPathResults.Abar_left =
993  currentPathResults.Abar_right =
995  currentPathResults.Abar = computeEffectiveBarAttenuation(
996  currentPathResults.Abar_top, currentPathResults.Abar_left, currentPathResults.Abar_right);
997 
998  currentPathResults.A = currentPathResults.Adiv + currentPathResults.Aatm + currentPathResults.Agr +
999  currentPathResults.Abar;
1000 
1001  // Get source power level and source directivity LW + DC
1002  currentPathResults.LW = OSpectreOctave(trajet.asrc.spectrum).round(); // Round spectrum to 2 digits
1003  // for compliance with ISO
1004  // TR 17534-3 values
1005 
1006  // Get source directivity correction
1007  currentPathResults.Dc =
1009 
1010  // If path is reflected one, then compute LW_image
1011  if (currentPathResults.pathType == TYTypeChemin::CHEMIN_REFLEX)
1012  {
1013  currentPathResults.LW =
1014  currentPathResults.LW +
1016  }
1017  currentPathResults.L = currentPathResults.LW + currentPathResults.Dc - currentPathResults.A;
1018  if (currentPathResults.pathType == TYTypeChemin::CHEMIN_REFLEX)
1019  {
1020  currentPathResults.L = currentPathResults.L * trajet.getChemin(i).getAttenuation(
1022  }
1023  currentPathResults.L.setType(SPECTRE_TYPE_LP); // L is a pressure spectrum
1024  SLp = SLp.sumdB(currentPathResults.L);
1025 
1026 #ifdef _DEBUG
1027  pathsResults.push_back(currentPathResults);
1028 #endif
1029  }
1030 
1031  // Trace results
1032  // TODO Remove trace or keep it only in Debug
1033 #ifdef _DEBUG
1035  pathsResults, SLp,
1036  *_pSolverAtmos); // Export results in a csv file for comparison with 17534-3 standard
1037 #endif
1038 
1039  trajet.build_tab_rays();
1040  trajet.reset(); // Erase paths array to (try to) spare memory
1041  return true;
1042 }
1043 
1044 bool TYAcousticModel9613Solver::computeSegmentEdgesHeights(double& hauteurA, double& hauteurB,
1045  const OSegment3D& meanSlope,
1046  const OSegment3D& ray) const
1047 {
1048  bool res = true;
1049  hauteurA = ray._ptA._z - meanSlope._ptA._z;
1050  hauteurB = ray._ptB._z - meanSlope._ptB._z;
1051  return res;
1052 }
double RADTODEG(double a)
Converts an angle from radians to degrees.
Definition: 3d.h:137
#define TYSEUILCONFONDUS
Definition: 3d.h:47
double DEGTORAD(double a)
Converts an angle from degrees to radians.
Definition: 3d.h:126
std::vector< OPoint3D > TabPoint3D
Definition: 3d.h:483
NxReal s
Definition: NxVec3.cpp:317
Representation of one of the most optimal path between source and receptor: S—>R Specific derivation ...
std::deque< TYChemin9613Solver > TYTabChemin9613Solver
TYChemin collection.
std::deque< TYEtape9613Solver > TYTabEtape9613Solver
TYEtape collection.
std::deque< TYEtape > TYTabEtape
TYEtape collection.
Definition: TYEtape.h:113
@ TYREFLEXION
Definition: acoustic_path.h:25
@ TYRECEPTEUR
Definition: acoustic_path.h:29
@ TYSOURCE
Definition: acoustic_path.h:28
@ TYDIFFRACTION
Definition: acoustic_path.h:24
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
double distFrom(const OPoint3D &pt) const
Computes the distance from this point to another.
Definition: 3d.cpp:371
Class to define a segment.
Definition: 3d.h:1141
virtual double longueur() const
Return the segment length.
Definition: 3d.cpp:1238
virtual int symetrieOf(const OPoint3D &pt, OPoint3D &ptSym) const
Return the symmetrical of a point.
Definition: 3d.cpp:1243
OPoint3D _ptA
Point A of the segment.
Definition: 3d.h:1253
virtual OVector3D toVector3D() const
Build a OVector3D from a segment used for the direction of the sources.
Definition: 3d.h:1240
virtual int intersects(const OSegment3D &seg, OPoint3D &pt, double seuilConfondus) const
Return the intersection point with another segment.
Definition: 3d.cpp:1267
OPoint3D _ptB
Point B of the segment.
Definition: 3d.h:1255
OSpectreAbstract & log(const double &base=10.0) const
Compute the log base n of this spectrum (n=10 by default).
Definition: spectre.cpp:409
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 & div(const OSpectreAbstract &spectre) const
Division of two spectrums.
Definition: spectre.cpp:278
void setDefaultValue(const double &valeur=TY_SPECTRE_DEFAULT_VALUE)
Definition: spectre.cpp:202
OSpectreAbstract & round()
Definition: spectre.cpp:578
OSpectreAbstract & sumdB(const OSpectreAbstract &spectre) const
Energetic sum of two spectrums.
Definition: spectre.cpp:176
static OSpectreOctave getLambda(const double &c)
Definition: spectre.cpp:1606
static OSpectreOctave getEmptyLinSpectre(const double &valInit=1.0E-20)
Create a physical quantity spectrum.
Definition: spectre.cpp:1631
double * getTabValReel() override
Get an array of the real values of the spectrum.
Definition: spectre.h:614
The 3D vector class.
Definition: 3d.h:298
double norme() const
Computes the length of this vector.
Definition: 3d.cpp:215
double scalar(const OVector3D &vector) const
Performs the scalar product between this object and another vector.
Definition: 3d.cpp:210
double dot(const OVector3D &v)
dot product (assuming an orthonormal reference frame)
Definition: 3d.h:362
void computeCheminSansEcran(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabChemin9613Solver &TabChemins, double distance, bool conditionFav=false) const
Compute the main path between source and receptor. In 9613 solver, this path includes all attenuation...
OSpectreOctave calculC3(const double &epaisseur) const
Compute the spectrum of the C3 factor used in the diffraction calculation.
OSpectreOctave calculAttDiffraction(const OSegment3D &ray, const double &re, const double &dss, const double &dsr, const double &width, const bool &vertical) const
Compute the attenuation from the diffraction on the screen.
virtual bool computeCheminsAvecEcran(const OSegment3D &rayon, const tympan::AcousticSource &source, const TabPoint3D &pts, const bool vertical, TYTabChemin9613Solver &TabChemins, double distance, const bool left) const
Compute barrier attenuation effect on the direct path for the considered geometrical path (top,...
bool solve(TYTrajet9613Solver &trajet)
Compute the source contributions to the receptor point.
bool addGroundSteps(const OPoint3D &ptStart, const OPoint3D &ptEnd, const tympan::AcousticSource &source, const bool &fromSource, TYTabEtape9613Solver &Etapes) const
Compute the different steps from a point to another via a reflection and a direct view.
TYAcousticModel9613Solver(TYSolver9613Solver &solver)
void computeWaveLength() override
Compute the wave length for the 9613Solver.
TYSolver9613Solver & _solver
Reference to the solver.
virtual OSpectreOctave calculKmeteo(const bool vertical, const double d_SS, const double d_SR, const double d, const double z, const double e, const OSpectreOctave &z_min) const
Compute Kmeteo, the correction factor for meteorological effects In Code_TYMPAN 9613Solver version 96...
bool computeGZone(const OPoint3D &ptDebut, const OPoint3D &ptFin, double &GZone, double &dpZone, const std::deque< TYSIntersection > &tabIntersect) const
Compute GZone and dpZone for the segment between ptDebut and ptFin.
bool computeSegmentEdgesHeights(double &hauteurA, double &hauteurB, const OSegment3D &meanSlope, const OSegment3D &ray) const
Compute heights relative to real ground, of the edges of a segment.
OSpectreOctave limAttDiffraction(const OSpectreOctave &sNC, const OSpectreOctave &C) const
Limit the screen attenuation value with a frequency dependent criteria.
OSpectreOctave computeEffectiveBarAttenuation(const OSpectreOctave &Abar_top, const OSpectreOctave &Abar_left, const OSpectreOctave &Abar_right)
virtual std::unique_ptr< TYChemin9613Solver > createChemin() const
void compute(const std::deque< TYSIntersection > &tabIntersect, TYTrajet9613Solver &trajet, TabPoint3D &ptsTop, TabPoint3D &ptsLeft, TabPoint3D &ptsRight)
Main entry point, trigger acoustic computations.
virtual void computeCheminReflexion(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &ray, const tympan::AcousticSource &source, TYTabChemin9613Solver &TabChemins, double distance) const
Compute the list of path generated by reflection on the vertical walls.
virtual OSpectreOctave calculZMin(const double C2, const OSpectreOctave &C3) const
Compute zmin, the min value of z for which the barrier attenuation Dz is null. This minimum distance ...
virtual OSpectreOctave calculDz(const double z, const double C2, const OSpectreOctave &C3, const OSpectreOctave &Kmeteo, const OSpectreOctave &zmin) const
Compute Dz, the barrier attenuation for each octave band in dB.
bool getGroundfactors(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &ray2D, double hs, double hr, double &Gs, double &Gm, double &Gr) const
Get ground factors for source, middle and receptor zones.
Acoustic model for the considered solver.
std::unique_ptr< AtmosphericConditions > _pSolverAtmos
void meanSlope(const OSegment3D &director, OSegment3D &slope) const
Create a segment corresponding to the projection of "director" segment on the ground.
Representation of one of the most optimal path between source and receptor: S—>R. The class TYChemin ...
OSpectreOctave & getAttenuation(const TYTypeAttenuation type)
Return attenuation of the path of the type.
double getLongueur()
Get/Set the path length.
Definition: TYChemin.h:99
const TYTypeChemin getType() const
Return the path type.
Definition: TYChemin.h:149
void setType(const TYTypeChemin &type)
Change the path type.
Definition: TYChemin.h:139
void setDistance(const double &distance)
Definition: TYChemin.h:130
void setLongueur(const double &longueur)
Definition: TYChemin.h:108
void build_eq_path(const T &tabEtapes)
build an acoustic_path from the tab of etapes
Definition: TYChemin.h:158
OSpectreOctave _Attenuation
attenuation Spectrum
OSpectreOctave _Absorption
absorption Spectrum
OPoint3D _pt
The starting point of this step.
Definition: TYEtape.h:109
ACOUSTIC_EVENT_TYPES _type
Acoustic event type.
Definition: TYEtape.h:108
static void exportResults17534(const std::vector< PathResults > pathsResults, const OSpectreOctave &SLp, const AtmosphericConditions &atmos)
void selectFaces(std::deque< TYSIntersection > &tabIntersect, const OSegment3D &rayon, const string &sourceVolumeId)
Delegate to _faceSelector the build of the array of intersections.
Definition: TYSolver.cpp:148
This class TYTrajet (journey) links a couple Source-Receptor and a collection of paths,...
size_t getNbChemins()
Return the number of path in *this (in addition to the direct path).
OSpectreOctave & getSpectreOct()
Get the spectrum in octave band at the receptor point Used to compute the pressure spectrum in octave...
void reset() override
Reset method.
TYTabChemin9613Solver & getChemins()
Return the collection of paths of *this.
TYChemin9613Solver getChemin(int index)
Return a path thanks to its index.
double getDistance()
Get/Set the distance between source and receptor.
Definition: TYTrajet.h:75
void getPtSetPtRfromOSeg3D(OSegment3D &seg) const
Definition: TYTrajet.h:115
tympan::AcousticSource & asrc
Business source.
Definition: TYTrajet.h:126
Describes building material.
Definition: entities.hpp:64
Describes an acoustic source.
Definition: entities.hpp:394
string volume_id
Volume id.
Definition: entities.hpp:404
SourceDirectivityInterface * directivity
Pointer to the source directivity.
Definition: entities.hpp:403
Spectrum spectrum
Associated spectrum.
Definition: entities.hpp:402
static LPSolverConfiguration get()
Get the configuration.
Definition: config.cpp:94
virtual Spectrum lwAdjustment(Vector direction, double distance)=0
< Pure virtual method to return directivity of the Source
This file provides class for solver configuration.
Math library.
boost::shared_ptr< SolverConfiguration > LPSolverConfiguration
Definition: interfaces.h:25
@ SPECTRE_TYPE_LP
Definition: spectre.h:31
@ SPECTRE_TYPE_AUTRE
Definition: spectre.h:32
@ SPECTRE_TYPE_ABSO
Definition: spectre.h:29
OSpectreOctave Dz_top
OSpectreOctave Abar_left
OSpectreOctave Aatm
OSpectreOctave Agr_r
OSpectreOctave A
OSpectreOctave Abar
OSpectreOctave Abar_top
OSpectreOctave L
OSpectreOctave Agr_s
OSpectreOctave Dc
OSpectreOctave Abar_right
OSpectreOctave Adiv
OSpectreOctave Dz_right
OSpectreOctave Agr
TYTypeChemin pathType
OSpectreOctave LW
OSpectreOctave Agr_m
OSpectreOctave Dz_left
Data structure for intersections.
bool isInfra
Flag to define if is a infrastructure face.
bool bIntersect[2]
Flag to indicate the face cuts vertical plane ([0]) or horizontal plane ([1])
boost::shared_ptr< tympan::AcousticFaceGeomData > pFaceGeomData
OSegment3D segInter[2]
tympan::AcousticMaterialBase * material
Pointer to a material.