40 double c_9613_2 = 340.0;
48 bool vertical =
true, horizontal =
false;
49 bool left =
true, right =
false;
54 bool conditionFav =
false;
58 assert(config->DSWindDirection >= 0 && config->DSWindDirection <= 360);
60 double windRadian =
DEGTORAD(config->DSWindDirection);
63 propaDirection.
_z = 0;
66 (windDirection.
norme() * propaDirection.
norme())));
67 assert(180 >= angle >= 0);
68 assert(180 >= config->AngleFavorable >= 0);
70 if (angle <= config->AngleFavorable)
90 if (ptsTop.size() > 1 || ptsLeft.size() > 1 || ptsRight.size() > 1)
117 const bool left)
const
124 tabPaths[0].setAttenuationBarWhenNoPath(vertical, left);
132 OPoint3D lastPt(pts[pts.size() - 1]);
135 double pathLength = 0.0;
141 double tempLength = curSegment.
longueur();
151 tabSteps.push_back(steps[0]);
152 pathLength += tempLength;
162 for (
unsigned int i = 1; i < pts.size() - 1; i++)
164 width += (
OSegment3D(pts[i], pts[i + 1])).longueur();
170 tabSteps.push_back(step);
181 tabSteps.push_back(steps[0]);
182 pathLength += tempLength;
197 tabSteps.push_back(step);
206 tabPaths.push_back(path);
209 tabPaths[0].computeBarAttenuation(Dz, vertical, left);
229 curStep.
_pt = ptStart;
243 steps.push_back(curStep);
252 bool conditionFav)
const
269 double Gs{0.0}, Gm{0.0}, Gr{0.0};
270 double hs{0.0}, hr{0.0};
280 tabEtapes.push_back(Etapes[0]);
284 TabChemin.push_back(chemin);
290 const OSegment3D& ray2D,
double hs,
double hr,
double& Gs,
291 double& Gm,
double& Gr)
const
293 double heightRatio = 30.0;
303 double dp = SR.norme();
310 if (heightRatio * hs < dp)
312 ptGSrcZone = ptStartProj + SR * heightRatio * hs;
316 ptGSrcZone = ptStartProj + SR * dp;
320 if (heightRatio * hr < dp)
322 ptGRcpZone = ptEndProj + (-1.0) * SR * heightRatio * hr;
326 ptGRcpZone = ptEndProj + (-1.0) * SR * dp;
330 double GZone{0.0}, dpZone{0.0};
331 computeGZone(ptStartProj, ptGSrcZone, GZone, dpZone, tabIntersect);
340 computeGZone(ptGRcpZone, ptEndProj, GZone, dpZone, tabIntersect);
349 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersect);
363 const std::deque<TYSIntersection>& tabIntersectDownSegment,
365 double hr,
double& Gs,
double& Gm,
double& Gr)
const
367 double heightRatio = 30.0;
386 double dp = dpSO + dpOR;
393 bool bPtGSrcZoneInSO{
false};
394 bool bPtGRcpZoneInOR{
false};
397 if (heightRatio * hs < dpSO)
400 bPtGSrcZoneInSO =
true;
401 ptGSrcZone = ptSrc2D + (SO)*heightRatio * hs;
403 else if (heightRatio * hs < dp)
406 ptGSrcZone = ptO2D + (OR) * (heightRatio * hs - dpSO);
410 ptGSrcZone = ptO2D + (OR)*dpOR;
414 double GZone{0.0}, dpZone{0.0};
417 computeGZone(ptSrc2D, ptGSrcZone, GZone, dpZone, tabIntersectUpSegment);
421 double Gs1{0.0}, dp1{0.0}, Gs2{0.0}, dpOGs{0.0};
422 computeGZone(ptSrc2D, ptO2D, Gs1, dp1, tabIntersectUpSegment);
423 computeGZone(ptO2D, ptGSrcZone, Gs2, dpOGs, tabIntersectDownSegment);
425 dpZone = dp1 + dpOGs;
438 if (heightRatio * hr < dpOR)
441 bPtGRcpZoneInOR =
true;
442 ptGRcpZone = ptRcp2D + (-1.0) * OR * heightRatio * hr;
444 else if (heightRatio * hr < dp)
447 ptGRcpZone = ptO2D + (-1.0) * SO * (heightRatio * hr - dpOR);
451 ptGRcpZone = ptO2D + (-1.0) * SO * dpSO;
458 computeGZone(ptGRcpZone, ptRcp2D, GZone, dpZone, tabIntersectDownSegment);
462 double Gr1{0.0}, dp2{0.0}, Gr2{0.0}, dpGrO{0.0};
463 computeGZone(ptGRcpZone, ptO2D, Gr1, dpGrO, tabIntersectUpSegment);
464 computeGZone(ptO2D, ptRcp2D, Gr2, dp2, tabIntersectDownSegment);
467 dpZone = dpGrO + dp2;
481 if (bPtGSrcZoneInSO && !bPtGRcpZoneInOR)
483 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectUpSegment);
486 else if (!bPtGSrcZoneInSO && bPtGRcpZoneInOR)
488 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectDownSegment);
491 else if (bPtGSrcZoneInSO)
493 double Gm1{0.0}, dpm1{0.0}, Gm2{0.0}, dpm2{0.0};
494 computeGZone(ptGSrcZone, ptO2D, Gm1, dpm1, tabIntersectUpSegment);
495 computeGZone(ptO2D, ptGRcpZone, Gm2, dpm2, tabIntersectDownSegment);
497 dpZone = dpm1 + dpm2;
502 double Gm1{0.0}, dpm1{0.0}, Gm2{0.0}, dpm2{0.0};
503 computeGZone(ptGRcpZone, ptO2D, Gm1, dpm1, tabIntersectUpSegment);
504 computeGZone(ptO2D, ptGSrcZone, Gm2, dpm2, tabIntersectDownSegment);
506 dpZone = dpm1 + dpm2;
526 for (
unsigned int i = 0; i < TY_SPECTRE_OCT_NB_ELMT; i++)
541 const std::deque<TYSIntersection>& tabIntersect)
const
546 std::unordered_map<OVector3D, double, OVector3DHash> mapResultSegFactorG;
552 size_t nbTriangles = tabIntersect.size();
553 double currentG = 0.0;
561 for (
unsigned int i = 0; i < nbTriangles; i++)
571 OSegment3D currentSeg = tabIntersect[i].segInter[0];
572 currentG = tabIntersect[i].material->get_ISO9613_G();
578 OSegment3D segAB{ptDebutCurrentProj, ptFinCurrentProj};
579 OVector3D AB{ptDebutCurrentProj, ptFinCurrentProj};
581 if (AB.scalar(DF) <= 0)
583 segAB = segAB.swap();
590 bool intersect =
true;
596 ptDebutResult = segAB._ptA;
602 ptFinResult = segAB._ptB;
607 ptFinResult = segZone.
_ptB;
620 ptDebutResult = segZone.
_ptA;
621 ptFinResult = segZone.
_ptB;
632 ptDebutResult = segZone.
_ptA;
633 ptFinResult = segAB._ptB;
639 OVector3D result{ptDebutResult, ptFinResult};
640 auto it = mapResultSegFactorG.find(result);
641 if (it != mapResultSegFactorG.end())
643 GZone = GZone + 0.5 * result.norme() * (currentG - it->second);
647 GZone = GZone + result.norme() * currentG;
648 dpZone += result.norme();
650 mapResultSegFactorG[result] = currentG;
661 double distance)
const
679 size_t nbFaces = tabIntersect.size();
682 for (
unsigned int i = 0; i < nbFaces; i++)
708 bool intersect =
false;
712 while ((j < nbFaces) && (!intersect))
720 segInter = tabIntersect[j].segInter[1];
753 tabEtapes.push_back(Etape);
760 tabEtapes.push_back(Etape);
771 double dp = raySO.
longueur() + rayOR.longueur();
774 double Gs{0.0}, Gm{0.0}, Gr{0.0};
775 double hs{0.0}, hr{0.0};
780 std::deque<TYSIntersection> tabIntersectUpSegment, tabIntersectDownSegment;
785 getGroundfactors(tabIntersectUpSegment, tabIntersectDownSegment, raySO, rayOR, hs, hr, Gs, Gm,
794 TabChemins.push_back(Chemin);
814 const double oneThird = 1.0 / 3.0;
816 opLambda =
_lambda * (5.0 / width);
817 opLambda = opLambda * opLambda;
820 C3 = C3.
div(opLambda + oneThird);
829 const double& dss,
const double& dsr,
831 const bool& vertical)
const
844 z = z <= 0 ? 0.0 : z;
847 if (z > 0.0 && vertical)
849 Kmeteo = exp(-(1.0 / 2000.0) * sqrt(dss * dsr * rd / (2 * z)));
874 double lim20dB = 20.0;
875 double lim25dB = 25.0;
880 for (
unsigned int i = 0; i < sNC.
getNbValues(); i++)
884 valeur = valeur < lim0dB ? lim0dB : valeur;
888 valeur = valeur > lim20dB ? lim20dB : valeur;
892 valeur = valeur > lim25dB ? lim25dB : valeur;
895 s.getTabValReel()[i] = valeur;
905 std::vector<PathResults> pathsResults;
913 for (
unsigned int i = 0; i < trajet.
getNbChemins(); i++)
915 currentPathResults.
path_id = i;
917 float minSRDistance = config->MinSRDistance;
948 currentPathResults.
A = currentPathResults.
Adiv + currentPathResults.
Aatm + currentPathResults.
Agr_s +
949 currentPathResults.
Agr_r + currentPathResults.
Agr_m + currentPathResults.
Abar;
957 currentPathResults.
Dc =
963 currentPathResults.
LW =
964 currentPathResults.
LW +
967 currentPathResults.
L = currentPathResults.
LW + currentPathResults.
Dc - currentPathResults.
A;
969 SLp = SLp.
sumdB(currentPathResults.
L);
972 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
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.
OSpectreAbstract & invMult(const double &coefficient=1.0) const
Division of a double constant by this 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)
void computeWaveLength() override
Compute the wave length for the 9613Solver.
TYSolver9613Solver & _solver
Reference to the solver.
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)
void compute(const std::deque< TYSIntersection > &tabIntersect, TYTrajet9613Solver &trajet, TabPoint3D &ptsTop, TabPoint3D &ptsLeft, TabPoint3D &ptsRight)
Main entry point, trigger acoustic computations.
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.
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.
void calcAttenuation(const TYTabEtape9613Solver &tabEtapes, const AtmosphericConditions &atmos, double dp=0.0, double hs=0.0, double hr=0.0, double Gs=0.5, double Gm=0.5, double Gr=0.5)
Compute the global attenuation on the path.
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.