45 double c_9613_2 = 340.0;
53 bool vertical =
true, horizontal =
false;
54 bool left =
true, right =
false;
59 bool conditionFav =
false;
63 assert(config->DSWindDirection >= 0 && config->DSWindDirection <= 360);
65 double windRadian =
DEGTORAD(config->DSWindDirection);
68 propaDirection.
_z = 0;
71 (windDirection.
norme() * propaDirection.
norme())));
72 assert(180 >= angle >= 0);
73 assert(180 >= config->AngleFavorable >= 0);
75 if (angle <= config->AngleFavorable)
95 if (ptsTop.size() > 1 || ptsLeft.size() > 1 || ptsRight.size() > 1)
122 const bool left)
const
129 tabPaths[0].setAttenuationBarWhenNoPath(vertical, left);
137 OPoint3D lastPt(pts[pts.size() - 1]);
140 double pathLength = 0.0;
146 double tempLength = curSegment.
longueur();
156 tabSteps.push_back(steps[0]);
157 pathLength += tempLength;
167 for (
unsigned int i = 1; i < pts.size() - 1; i++)
169 width += (
OSegment3D(pts[i], pts[i + 1])).longueur();
175 tabSteps.push_back(step);
186 tabSteps.push_back(steps[0]);
187 pathLength += tempLength;
202 tabSteps.push_back(step);
211 tabPaths.push_back(path);
214 tabPaths[0].computeBarAttenuation(Dz, vertical, left);
234 curStep.
_pt = ptStart;
248 steps.push_back(curStep);
257 bool conditionFav)
const
263 std::unique_ptr<TYChemin9613Solver> chemin =
createChemin();
275 double Gs{0.0}, Gm{0.0}, Gr{0.0};
276 double hs{0.0}, hr{0.0};
286 tabEtapes.push_back(Etapes[0]);
287 chemin->setLongueur(distance);
288 chemin->setDistance(distance);
289 chemin->calcAttenuation(tabEtapes, *
_pSolverAtmos, dp, hs, hr, Gs, Gm, Gr);
290 TabChemin.push_back(*chemin);
296 const OSegment3D& ray2D,
double hs,
double hr,
double& Gs,
297 double& Gm,
double& Gr)
const
299 double heightRatio = 30.0;
309 double dp = SR.norme();
316 if (heightRatio * hs < dp)
318 ptGSrcZone = ptStartProj + SR * heightRatio * hs;
322 ptGSrcZone = ptStartProj + SR * dp;
326 if (heightRatio * hr < dp)
328 ptGRcpZone = ptEndProj + (-1.0) * SR * heightRatio * hr;
332 ptGRcpZone = ptEndProj + (-1.0) * SR * dp;
336 double GZone{0.0}, dpZone{0.0};
337 computeGZone(ptStartProj, ptGSrcZone, GZone, dpZone, tabIntersect);
346 computeGZone(ptGRcpZone, ptEndProj, GZone, dpZone, tabIntersect);
355 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersect);
369 const std::deque<TYSIntersection>& tabIntersectDownSegment,
371 double hr,
double& Gs,
double& Gm,
double& Gr)
const
373 double heightRatio = 30.0;
392 double dp = dpSO + dpOR;
399 bool bPtGSrcZoneInSO{
false};
400 bool bPtGRcpZoneInOR{
false};
403 if (heightRatio * hs < dpSO)
406 bPtGSrcZoneInSO =
true;
407 ptGSrcZone = ptSrc2D + (SO)*heightRatio * hs;
409 else if (heightRatio * hs < dp)
412 ptGSrcZone = ptO2D + (OR) * (heightRatio * hs - dpSO);
416 ptGSrcZone = ptO2D + (OR)*dpOR;
420 double GZone{0.0}, dpZone{0.0};
423 computeGZone(ptSrc2D, ptGSrcZone, GZone, dpZone, tabIntersectUpSegment);
427 double Gs1{0.0}, dp1{0.0}, Gs2{0.0}, dpOGs{0.0};
428 computeGZone(ptSrc2D, ptO2D, Gs1, dp1, tabIntersectUpSegment);
429 computeGZone(ptO2D, ptGSrcZone, Gs2, dpOGs, tabIntersectDownSegment);
431 dpZone = dp1 + dpOGs;
444 if (heightRatio * hr < dpOR)
447 bPtGRcpZoneInOR =
true;
448 ptGRcpZone = ptRcp2D + (-1.0) * OR * heightRatio * hr;
450 else if (heightRatio * hr < dp)
453 ptGRcpZone = ptO2D + (-1.0) * SO * (heightRatio * hr - dpOR);
457 ptGRcpZone = ptO2D + (-1.0) * SO * dpSO;
464 computeGZone(ptGRcpZone, ptRcp2D, GZone, dpZone, tabIntersectDownSegment);
468 double Gr1{0.0}, dp2{0.0}, Gr2{0.0}, dpGrO{0.0};
469 computeGZone(ptGRcpZone, ptO2D, Gr1, dpGrO, tabIntersectUpSegment);
470 computeGZone(ptO2D, ptRcp2D, Gr2, dp2, tabIntersectDownSegment);
473 dpZone = dpGrO + dp2;
487 if (bPtGSrcZoneInSO && !bPtGRcpZoneInOR)
489 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectUpSegment);
492 else if (!bPtGSrcZoneInSO && bPtGRcpZoneInOR)
494 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectDownSegment);
497 else if (bPtGSrcZoneInSO)
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);
503 dpZone = dpm1 + dpm2;
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);
512 dpZone = dpm1 + dpm2;
532 for (
unsigned int i = 0; i < TY_SPECTRE_OCT_NB_ELMT; i++)
547 const std::deque<TYSIntersection>& tabIntersect)
const
552 std::unordered_map<OVector3D, double, OVector3DHash> mapResultSegFactorG;
558 size_t nbTriangles = tabIntersect.size();
559 double currentG = 0.0;
567 for (
unsigned int i = 0; i < nbTriangles; i++)
577 OSegment3D currentSeg = tabIntersect[i].segInter[0];
578 currentG = tabIntersect[i].material->get_ISO9613_G();
584 OSegment3D segAB{ptDebutCurrentProj, ptFinCurrentProj};
585 OVector3D AB{ptDebutCurrentProj, ptFinCurrentProj};
587 if (AB.scalar(DF) <= 0)
589 segAB = segAB.swap();
596 bool intersect =
true;
602 ptDebutResult = segAB._ptA;
608 ptFinResult = segAB._ptB;
613 ptFinResult = segZone.
_ptB;
626 ptDebutResult = segZone.
_ptA;
627 ptFinResult = segZone.
_ptB;
638 ptDebutResult = segZone.
_ptA;
639 ptFinResult = segAB._ptB;
645 OVector3D result{ptDebutResult, ptFinResult};
646 auto it = mapResultSegFactorG.find(result);
647 if (it != mapResultSegFactorG.end())
649 GZone = GZone + 0.5 * result.norme() * (currentG - it->second);
653 GZone = GZone + result.norme() * currentG;
654 dpZone += result.norme();
656 mapResultSegFactorG[result] = currentG;
667 double distance)
const
685 size_t nbFaces = tabIntersect.size();
690 for (
unsigned int i = 0; i < nbFaces; i++)
716 bool intersect =
false;
720 while ((j < nbFaces) && (!intersect))
728 segInter = tabIntersect[j].segInter[1];
761 tabEtapes.push_back(Etape);
768 tabEtapes.push_back(Etape);
779 double dp = raySO.
longueur() + rayOR.longueur();
782 double Gs{0.0}, Gm{0.0}, Gr{0.0};
783 double hs{0.0}, hr{0.0};
788 std::deque<TYSIntersection> tabIntersectUpSegment, tabIntersectDownSegment;
793 getGroundfactors(tabIntersectUpSegment, tabIntersectDownSegment, raySO, rayOR, hs, hr, Gs, Gm,
796 std::unique_ptr<TYChemin9613Solver> chemin =
createChemin();
798 chemin->setLongueur(pathLength);
799 chemin->setDistance(distance);
800 chemin->calcAttenuation(tabEtapes, *
_pSolverAtmos, dp, hs, hr, Gs, Gm, Gr);
802 chemin->setMinimalExtensionConditionReflection(filter);
804 TabChemins.push_back(*chemin);
824 const double oneThird = 1.0 / 3.0;
826 opLambda =
_lambda * (5.0 / width);
827 opLambda = opLambda * opLambda;
830 C3 = C3.
div(opLambda + oneThird);
839 const double& dss,
const double& dsr,
841 const bool& vertical)
const
853 z = z <= 0 ? 0.0 : z;
877 const double d_SR,
const double d,
const double z,
883 if (z > 0.0 && vertical)
885 Kmeteo = exp(-(1.0 / 2000.0) * sqrt(d_SS * d_SR * d / (2 * z)));
905 for (std::size_t i = 0; i < TY_SPECTRE_OCT_NB_ELMT; ++i)
909 dz[i] = 10.0 * std::log10(3.0 + (C2 / lambda[i]) * c3[i] * z * kmeteo[i]);
921 double lim20dB = 20.0;
922 double lim25dB = 25.0;
927 for (
unsigned int i = 0; i < sNC.
getNbValues(); i++)
931 valeur = valeur < lim0dB ? lim0dB : valeur;
935 valeur = valeur > lim20dB ? lim20dB : valeur;
939 valeur = valeur > lim25dB ? lim25dB : valeur;
942 s.getTabValReel()[i] = valeur;
952 std::vector<PathResults> pathsResults;
960 for (
unsigned int i = 0; i < trajet.
getNbChemins(); i++)
962 currentPathResults.
path_id = i;
964 float minSRDistance = config->MinSRDistance;
999 currentPathResults.
Acurv =
1001 currentPathResults.
Amisc = currentPathResults.
Amisc + currentPathResults.
Acurv;
1004 currentPathResults.
A = currentPathResults.
Adiv + currentPathResults.
Aatm + currentPathResults.
Agr +
1005 currentPathResults.
Abar + currentPathResults.
Amisc;
1013 currentPathResults.
Dc =
1019 currentPathResults.
LW =
1020 currentPathResults.
LW +
1023 currentPathResults.
L = currentPathResults.
LW + currentPathResults.
Dc - currentPathResults.
A;
1029 filterComplement = filterComplement * (-1.0) + 1.0;
1030 currentPathResults.
L = currentPathResults.
L * filter +
OSpectreOctave{} * filterComplement;
1033 SLp = SLp.
sumdB(currentPathResults.
L);
1036 pathsResults.push_back(currentPathResults);
double RADTODEG(double a)
Converts an angle from radians to degrees.
double DEGTORAD(double a)
Converts an angle from degrees to radians.
std::vector< OPoint3D > TabPoint3D
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.
double _y
y coordinate of OCoord3D
double _z
z coordinate of OCoord3D
double _x
x coordinate of OCoord3D
double distFrom(const OPoint3D &pt) const
Computes the distance from this point to another.
Class to define a segment.
virtual double longueur() const
Return the segment length.
virtual int symetrieOf(const OPoint3D &pt, OPoint3D &ptSym) const
Return the symmetrical of a point.
OPoint3D _ptA
Point A of the segment.
virtual OVector3D toVector3D() const
Build a OVector3D from a segment used for the direction of the sources.
virtual int intersects(const OSegment3D &seg, OPoint3D &pt, double seuilConfondus) const
Return the intersection point with another segment.
OPoint3D _ptB
Point B of the segment.
OSpectreAbstract & log(const double &base=10.0) const
Compute the log base n of this spectrum (n=10 by default).
unsigned int getNbValues() const
Number of values in the spectrum.
void setType(TYSpectreType type)
Set the spectrum type.
OSpectreAbstract & div(const OSpectreAbstract &spectre) const
Division of two spectrums.
void setDefaultValue(const double &valeur=TY_SPECTRE_DEFAULT_VALUE)
OSpectreAbstract & round()
OSpectreAbstract & sumdB(const OSpectreAbstract &spectre) const
Energetic sum of two spectrums.
static OSpectreOctave getLambda(const double &c)
static OSpectreOctave getEmptyLinSpectre(const double &valInit=1.0E-20)
Create a physical quantity spectrum.
double * getTabValReel() override
Get an array of the real values of the spectrum.
double norme() const
Computes the length of this vector.
double scalar(const OVector3D &vector) const
Performs the scalar product between this object and another vector.
double dot(const OVector3D &v)
dot product (assuming an orthonormal reference frame)
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.
OSpectreOctave _absoNulle
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.
const TYTypeChemin getType() const
Return the path type.
void setType(const TYTypeChemin &type)
Change the path type.
void setDistance(const double &distance)
void setLongueur(const double &longueur)
void build_eq_path(const T &tabEtapes)
build an acoustic_path from the tab of etapes
OSpectreOctave _Attenuation
attenuation Spectrum
OSpectreOctave _Absorption
absorption Spectrum
OPoint3D _pt
The starting point of this step.
ACOUSTIC_EVENT_TYPES _type
Acoustic event type.
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.
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.
void getPtSetPtRfromOSeg3D(OSegment3D &seg) const
tympan::AcousticSource & asrc
Business source.
Describes building material.
Describes an acoustic source.
string volume_id
Volume id.
SourceDirectivityInterface * directivity
Pointer to the source directivity.
Spectrum spectrum
Associated spectrum.
static LPSolverConfiguration get()
Get the configuration.
virtual Spectrum lwAdjustment(Vector direction, double distance)=0
< Pure virtual method to return directivity of the Source
This file provides class for solver configuration.
boost::shared_ptr< SolverConfiguration > LPSolverConfiguration
OSpectreOctave Abar_right
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])
tympan::AcousticMaterialBase * material
Pointer to a material.