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