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
258 std::unique_ptr<TYChemin9613Solver> chemin =
createChemin();
270 double Gs{0.0}, Gm{0.0}, Gr{0.0};
271 double hs{0.0}, hr{0.0};
281 tabEtapes.push_back(Etapes[0]);
282 chemin->setLongueur(distance);
283 chemin->setDistance(distance);
284 chemin->calcAttenuation(tabEtapes, *
_pSolverAtmos, dp, hs, hr, Gs, Gm, Gr);
285 TabChemin.push_back(*chemin);
291 const OSegment3D& ray2D,
double hs,
double hr,
double& Gs,
292 double& Gm,
double& Gr)
const
294 double heightRatio = 30.0;
304 double dp = SR.norme();
311 if (heightRatio * hs < dp)
313 ptGSrcZone = ptStartProj + SR * heightRatio * hs;
317 ptGSrcZone = ptStartProj + SR * dp;
321 if (heightRatio * hr < dp)
323 ptGRcpZone = ptEndProj + (-1.0) * SR * heightRatio * hr;
327 ptGRcpZone = ptEndProj + (-1.0) * SR * dp;
331 double GZone{0.0}, dpZone{0.0};
332 computeGZone(ptStartProj, ptGSrcZone, GZone, dpZone, tabIntersect);
341 computeGZone(ptGRcpZone, ptEndProj, GZone, dpZone, tabIntersect);
350 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersect);
364 const std::deque<TYSIntersection>& tabIntersectDownSegment,
366 double hr,
double& Gs,
double& Gm,
double& Gr)
const
368 double heightRatio = 30.0;
387 double dp = dpSO + dpOR;
394 bool bPtGSrcZoneInSO{
false};
395 bool bPtGRcpZoneInOR{
false};
398 if (heightRatio * hs < dpSO)
401 bPtGSrcZoneInSO =
true;
402 ptGSrcZone = ptSrc2D + (SO)*heightRatio * hs;
404 else if (heightRatio * hs < dp)
407 ptGSrcZone = ptO2D + (OR) * (heightRatio * hs - dpSO);
411 ptGSrcZone = ptO2D + (OR)*dpOR;
415 double GZone{0.0}, dpZone{0.0};
418 computeGZone(ptSrc2D, ptGSrcZone, GZone, dpZone, tabIntersectUpSegment);
422 double Gs1{0.0}, dp1{0.0}, Gs2{0.0}, dpOGs{0.0};
423 computeGZone(ptSrc2D, ptO2D, Gs1, dp1, tabIntersectUpSegment);
424 computeGZone(ptO2D, ptGSrcZone, Gs2, dpOGs, tabIntersectDownSegment);
426 dpZone = dp1 + dpOGs;
439 if (heightRatio * hr < dpOR)
442 bPtGRcpZoneInOR =
true;
443 ptGRcpZone = ptRcp2D + (-1.0) * OR * heightRatio * hr;
445 else if (heightRatio * hr < dp)
448 ptGRcpZone = ptO2D + (-1.0) * SO * (heightRatio * hr - dpOR);
452 ptGRcpZone = ptO2D + (-1.0) * SO * dpSO;
459 computeGZone(ptGRcpZone, ptRcp2D, GZone, dpZone, tabIntersectDownSegment);
463 double Gr1{0.0}, dp2{0.0}, Gr2{0.0}, dpGrO{0.0};
464 computeGZone(ptGRcpZone, ptO2D, Gr1, dpGrO, tabIntersectUpSegment);
465 computeGZone(ptO2D, ptRcp2D, Gr2, dp2, tabIntersectDownSegment);
468 dpZone = dpGrO + dp2;
482 if (bPtGSrcZoneInSO && !bPtGRcpZoneInOR)
484 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectUpSegment);
487 else if (!bPtGSrcZoneInSO && bPtGRcpZoneInOR)
489 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectDownSegment);
492 else if (bPtGSrcZoneInSO)
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);
498 dpZone = dpm1 + dpm2;
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);
507 dpZone = dpm1 + dpm2;
527 for (
unsigned int i = 0; i < TY_SPECTRE_OCT_NB_ELMT; i++)
542 const std::deque<TYSIntersection>& tabIntersect)
const
547 std::unordered_map<OVector3D, double, OVector3DHash> mapResultSegFactorG;
553 size_t nbTriangles = tabIntersect.size();
554 double currentG = 0.0;
562 for (
unsigned int i = 0; i < nbTriangles; i++)
572 OSegment3D currentSeg = tabIntersect[i].segInter[0];
573 currentG = tabIntersect[i].material->get_ISO9613_G();
579 OSegment3D segAB{ptDebutCurrentProj, ptFinCurrentProj};
580 OVector3D AB{ptDebutCurrentProj, ptFinCurrentProj};
582 if (AB.scalar(DF) <= 0)
584 segAB = segAB.swap();
591 bool intersect =
true;
597 ptDebutResult = segAB._ptA;
603 ptFinResult = segAB._ptB;
608 ptFinResult = segZone.
_ptB;
621 ptDebutResult = segZone.
_ptA;
622 ptFinResult = segZone.
_ptB;
633 ptDebutResult = segZone.
_ptA;
634 ptFinResult = segAB._ptB;
640 OVector3D result{ptDebutResult, ptFinResult};
641 auto it = mapResultSegFactorG.find(result);
642 if (it != mapResultSegFactorG.end())
644 GZone = GZone + 0.5 * result.norme() * (currentG - it->second);
648 GZone = GZone + result.norme() * currentG;
649 dpZone += result.norme();
651 mapResultSegFactorG[result] = currentG;
662 double distance)
const
680 size_t nbFaces = tabIntersect.size();
683 for (
unsigned int i = 0; i < nbFaces; i++)
709 bool intersect =
false;
713 while ((j < nbFaces) && (!intersect))
721 segInter = tabIntersect[j].segInter[1];
754 tabEtapes.push_back(Etape);
761 tabEtapes.push_back(Etape);
772 double dp = raySO.
longueur() + rayOR.longueur();
775 double Gs{0.0}, Gm{0.0}, Gr{0.0};
776 double hs{0.0}, hr{0.0};
781 std::deque<TYSIntersection> tabIntersectUpSegment, tabIntersectDownSegment;
786 getGroundfactors(tabIntersectUpSegment, tabIntersectDownSegment, raySO, rayOR, hs, hr, Gs, Gm,
789 std::unique_ptr<TYChemin9613Solver> chemin =
createChemin();
791 chemin->setLongueur(pathLength);
792 chemin->setDistance(distance);
793 chemin->calcAttenuation(tabEtapes, *
_pSolverAtmos, dp, hs, hr, Gs, Gm, Gr);
804 chemin->calcMinimalExtensionCondition(S, O, R, a, h, normal);
806 TabChemins.push_back(*chemin);
826 const double oneThird = 1.0 / 3.0;
828 opLambda =
_lambda * (5.0 / width);
829 opLambda = opLambda * opLambda;
832 C3 = C3.
div(opLambda + oneThird);
841 const double& dss,
const double& dsr,
843 const bool& vertical)
const
855 z = z <= 0 ? 0.0 : z;
879 const double d_SR,
const double d,
const double z,
885 if (z > 0.0 && vertical)
887 Kmeteo = exp(-(1.0 / 2000.0) * sqrt(d_SS * d_SR * d / (2 * z)));
907 for (std::size_t i = 0; i < TY_SPECTRE_OCT_NB_ELMT; ++i)
911 dz[i] = 10.0 * std::log10(3.0 + (C2 / lambda[i]) * c3[i] * z * kmeteo[i]);
923 double lim20dB = 20.0;
924 double lim25dB = 25.0;
929 for (
unsigned int i = 0; i < sNC.
getNbValues(); i++)
933 valeur = valeur < lim0dB ? lim0dB : valeur;
937 valeur = valeur > lim20dB ? lim20dB : valeur;
941 valeur = valeur > lim25dB ? lim25dB : valeur;
944 s.getTabValReel()[i] = valeur;
954 std::vector<PathResults> pathsResults;
962 for (
unsigned int i = 0; i < trajet.
getNbChemins(); i++)
964 currentPathResults.
path_id = i;
966 float minSRDistance = config->MinSRDistance;
998 currentPathResults.
A = currentPathResults.
Adiv + currentPathResults.
Aatm + currentPathResults.
Agr +
999 currentPathResults.
Abar;
1007 currentPathResults.
Dc =
1013 currentPathResults.
LW =
1014 currentPathResults.
LW +
1017 currentPathResults.
L = currentPathResults.
LW + currentPathResults.
Dc - currentPathResults.
A;
1024 SLp = SLp.
sumdB(currentPathResults.
L);
1027 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)
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.
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])
boost::shared_ptr< tympan::AcousticFaceGeomData > pFaceGeomData
tympan::AcousticMaterialBase * material
Pointer to a material.