SUMO - Simulation of Urban MObility
CEP.cs
Go to the documentation of this file.
1 #define FLEET
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7 
8 namespace PHEMlightdll
9 {
10  public class CEP
11  {
12  //--------------------------------------------------------------------------------------------------
13  // Constructors
14  //--------------------------------------------------------------------------------------------------
15 
16  #region Constructor
17  public CEP(bool heavyVehicle,
18  double vehicleMass,
19  double vehicleLoading,
20  double vehicleMassRot,
21  double crossArea,
22  double cWValue,
23  double f0,
24  double f1,
25  double f2,
26  double f3,
27  double f4,
28  double axleRatio,
29  List<double> transmissionGearRatios,
30  double auxPower,
31  double ratedPower,
32  double engineIdlingSpeed,
33  double engineRatedSpeed,
34  double effictiveWheelDiameter,
35  double pNormV0,
36  double pNormP0,
37  double pNormV1,
38  double pNormP1,
39  string vehicelFuelType,
40  List<List<double>> matrixFC,
41  List<string> headerLinePollutants,
42  List<List<double>> matrixPollutants,
43  List<List<double>> matrixSpeedRotational,
44  List<List<double>> normedDragTable,
45  double idlingFC,
46  List<double> idlingPollutants)
47  {
48  _resistanceF0 = f0;
49  _resistanceF1 = f1;
50  _resistanceF2 = f2;
51  _resistanceF3 = f3;
52  _resistanceF4 = f4;
53  _cWValue = cWValue;
54  _crossSectionalArea = crossArea;
55  _massVehicle = vehicleMass;
56  _vehicleLoading = vehicleLoading;
57  _vehicleMassRot = vehicleMassRot;
58  _ratedPower = ratedPower;
59  _engineIdlingSpeed = engineIdlingSpeed;
60  _engineRatedSpeed = engineRatedSpeed;
61  _effectiveWheelDiameter = effictiveWheelDiameter;
62  _heavyVehicle = heavyVehicle;
63  _fuelType = vehicelFuelType;
64  _axleRatio = axleRatio;
65  _auxPower = auxPower;
66 
67  _pNormV0 = pNormV0 / 3.6;
68  _pNormP0 = pNormP0;
69  _pNormV1 = pNormV1 / 3.6;
70  _pNormP1 = pNormP1;
71 
72  List<string> pollutantIdentifier = new List<string>();
73  List<List<double>> pollutantMeasures = new List<List<double>>();
74  List<List<double>> normalizedPollutantMeasures = new List<List<double>>();
75 
76  // init pollutant identifiers
77  for (int i = 0; i < headerLinePollutants.Count; i++)
78  {
79  pollutantIdentifier.Add(headerLinePollutants[i]);
80  }
81 
82  // initialize measures
83  for (int i = 0; i < headerLinePollutants.Count; i++)
84  {
85  pollutantMeasures.Add(new List<double>());
86  normalizedPollutantMeasures.Add(new List<double>());
87  }
88 
89  // looping through matrix and assigning values for speed rotational table
90  _speedCurveRotational = new List<double>();
91  _speedPatternRotational = new List<double>();
92  _gearTransmissionCurve = new List<double>();
93  for (int i = 0; i < matrixSpeedRotational.Count; i++)
94  {
95  if (matrixSpeedRotational[i].Count != 3)
96  return;
97 
98  _speedPatternRotational.Add(matrixSpeedRotational[i][0] / 3.6);
99  _gearTransmissionCurve.Add(matrixSpeedRotational[i][1]);
100  _speedCurveRotational.Add(matrixSpeedRotational[i][2]);
101  }
102 
103  // looping through matrix and assigning values for drag table
104  _nNormTable = new List<double>();
105  _dragNormTable = new List<double>();
106  for (int i = 0; i < normedDragTable.Count; i++)
107  {
108  if (normedDragTable[i].Count != 2)
109  return;
110 
111  _nNormTable.Add(normedDragTable[i][0]);
112  _dragNormTable.Add(normedDragTable[i][1]);
113  }
114 
115  // looping through matrix and assigning values for Fuel consumption
116  _cepCurveFC = new List<double>();
117  _normedCepCurveFC = new List<double>();
118  _powerPatternFC = new List<double>();
119  _normalizedPowerPatternFC = new List<double>();
120  for (int i = 0; i < matrixFC.Count; i++)
121  {
122  if (matrixFC[i].Count != 2)
123  return;
124 
125  _powerPatternFC.Add(matrixFC[i][0] * _ratedPower);
126  _normalizedPowerPatternFC.Add(matrixFC[i][0]);
127  _cepCurveFC.Add(matrixFC[i][1] * _ratedPower);
128  _normedCepCurveFC.Add(matrixFC[i][1]);
129 
130  }
131 
132  _powerPatternPollutants = new List<double>();
133 
134  double pollutantMultiplyer = 1;
135 
137 
138  // looping through matrix and assigning values for pollutants
139  if (heavyVehicle)
140  {
142  _normalizingType = NormalizingType.RatedPower;
143  pollutantMultiplyer = _ratedPower;
144  }
145  else
146  {
148  _normalizingType = NormalizingType.DrivingPower;
149  }
150 
151  _normailzedPowerPatternPollutants = new List<double>();
152 
153  _cepNormalizedCurvePollutants = new Dictionary<string, List<double>>();
154 
155  int headerCount = headerLinePollutants.Count;
156  for (int i = 0; i < matrixPollutants.Count; i++)
157  {
158  for (int j = 0; j < matrixPollutants[i].Count; j++)
159  {
160  if (matrixPollutants[i].Count != headerCount + 1)
161  return;
162 
163  if (j == 0)
164  {
165  _normailzedPowerPatternPollutants.Add(matrixPollutants[i][j]);
166  _powerPatternPollutants.Add(matrixPollutants[i][j] * NormalizingPower);
167  }
168  else
169  {
170  pollutantMeasures[j - 1].Add(matrixPollutants[i][j] * pollutantMultiplyer);
171  normalizedPollutantMeasures[j - 1].Add(matrixPollutants[i][j]);
172  }
173  }
174  }
175 
176  _cepCurvePollutants = new Dictionary<string, List<double>>();
177  _idlingValuesPollutants = new Dictionary<string, double>();
178 
179  for (int i = 0; i < headerLinePollutants.Count; i++)
180  {
181  _cepCurvePollutants.Add(pollutantIdentifier[i], pollutantMeasures[i]);
182  _cepNormalizedCurvePollutants.Add(pollutantIdentifier[i], normalizedPollutantMeasures[i]);
183  _idlingValuesPollutants.Add(pollutantIdentifier[i], idlingPollutants[i] * pollutantMultiplyer);
184  }
185 
186  _idlingValueFC = idlingFC * _ratedPower;
187  }
188  #endregion
189 
190  #if FLEET
191  #region ConstrutorForFleetmix
192  private CEP(bool heavyVehicle,
193  double vehicleMass,
194  double vehicleLoading,
195  double vehicleMassRot,
196  double crossArea,
197  double cWValue,
198  double f0,
199  double f1,
200  double f2,
201  double f3,
202  double f4,
203  double axleRatio,
204  double auxPower,
205  double ratedPower,
206  double engineIdlingSpeed,
207  double engineRatedSpeed,
208  double effictiveWheelDiameter,
209  double pNormV0,
210  double pNormP0,
211  double pNormV1,
212  double pNormP1)
213  {
214  _resistanceF0 = f0;
215  _resistanceF1 = f1;
216  _resistanceF2 = f2;
217  _resistanceF3 = f3;
218  _resistanceF4 = f4;
219  _cWValue = cWValue;
220  _crossSectionalArea = crossArea;
221  _massVehicle = vehicleMass;
222  _vehicleLoading = vehicleLoading;
223  _vehicleMassRot = vehicleMassRot;
224  _ratedPower = ratedPower;
225  _engineIdlingSpeed = engineIdlingSpeed;
226  _engineRatedSpeed = engineRatedSpeed;
227  _effectiveWheelDiameter = effictiveWheelDiameter;
228 
229  _axleRatio = axleRatio;
230  _auxPower = auxPower;
231 
232  _pNormV0 = pNormV0 / 3.6;
233  _pNormP0 = pNormP0;
234  _pNormV1 = pNormV1 / 3.6;
235  _pNormP1 = pNormP1;
236 
237  _heavyVehicle = heavyVehicle;
238 
239  }
240  #endregion
241  #endif
242 
243  //--------------------------------------------------------------------------------------------------
244  // Members
245  //--------------------------------------------------------------------------------------------------
246 
247  #region HeavyVehicle
248  private bool _heavyVehicle;
249  public bool HeavyVehicle
250  {
251  get
252  {
253  return _heavyVehicle;
254  }
255  }
256  #endregion
257 
258  #region FuelType
259  private string _fuelType;
260  public string FuelType
261  {
262  get
263  {
264  return _fuelType;
265  }
266  }
267  #endregion
268 
269  #region NormalizingType
270  public enum NormalizingType
271  {
272  RatedPower,
274  }
277  {
278  get
279  {
280  return _normalizingType;
281  }
282  }
283  #endregion
284 
285  #region RatedPower
286  private double _ratedPower;
287  public double RatedPower
288  {
289  get
290  {
291  return _ratedPower;
292  }
293  set
294  {
295  _ratedPower = value;
296  }
297  }
298  #endregion
299 
300  #region NormalizingPower
301  private double _normalizingPower;
302  public double NormalizingPower
303  {
304  get
305  {
306  return _normalizingPower;
307  }
308  }
309  #endregion
310 
311  #region DrivingPower
312  private double _drivingPower;
313  public double DrivingPower
314  {
315  get
316  {
317  return _drivingPower;
318  }
319  set
320  {
321  _drivingPower = value;
322  }
323  }
324 
325  #endregion
326 
327  #region Private Members
328 
329  protected double _massVehicle;
330  protected double _vehicleLoading;
331  protected double _vehicleMassRot;
332  protected double _crossSectionalArea;
333  protected double _cWValue;
334  protected double _resistanceF0;
335  protected double _resistanceF1;
336  protected double _resistanceF2;
337  protected double _resistanceF3;
338  protected double _resistanceF4;
339  protected double _axleRatio;
340  protected double _auxPower;
341  protected double _pNormV0;
342  protected double _pNormP0;
343  protected double _pNormV1;
344  protected double _pNormP1;
345 
346  protected double _engineRatedSpeed;
347  protected double _engineIdlingSpeed;
348  protected double _effectiveWheelDiameter;
349 
350  protected List<double> _speedPatternRotational;
351  protected List<double> _powerPatternFC;
352  protected List<double> _normalizedPowerPatternFC;
353  protected List<double> _normailzedPowerPatternPollutants;
354  protected List<double> _powerPatternPollutants;
355 
356  protected List<double> _cepCurveFC;
357  protected List<double> _normedCepCurveFC;
358  protected List<double> _gearTransmissionCurve;
359  protected List<double> _speedCurveRotational;
360  protected Dictionary<string, List<double>> _cepCurvePollutants;
361  protected Dictionary<string, List<double>> _cepNormalizedCurvePollutants;
362  protected double _idlingValueFC;
363  protected Dictionary<string, double> _idlingValuesPollutants;
364 
365  protected List<double> _nNormTable;
366  protected List<double> _dragNormTable;
367 
368  #endregion
369 
370  //--------------------------------------------------------------------------------------------------
371  // Methods
372  //--------------------------------------------------------------------------------------------------
373 
374  #region CalcPower
375  public double CalcPower(double speed, double acc, double gradient)
376  {
377  //Declaration
378  double power = 0;
379  double rotFactor = GetRotationalCoeffecient(speed);
380  double powerAux = (_auxPower * _ratedPower);
381 
382  //Calculate the power
383  power += (_massVehicle + _vehicleLoading) * Constants.GRAVITY_CONST * (_resistanceF0 + _resistanceF1 * speed + _resistanceF4 * Math.Pow(speed, 4)) * speed;
384  power += (_crossSectionalArea * _cWValue * Constants.AIR_DENSITY_CONST / 2) * Math.Pow(speed, 3);
385  power += (_massVehicle * rotFactor + _vehicleMassRot + _vehicleLoading) * acc * speed;
386  power += (_massVehicle + _vehicleLoading) * Constants.GRAVITY_CONST * gradient * 0.01 * speed;
387  power /= 1000;
389  power += powerAux;
390 
391  //Return result
392  return power;
393  }
394  #endregion
395 
396  #region CalcEngPower
397  public double CalcEngPower(double power)
398  {
399  if (power < _powerPatternFC.First()) return _powerPatternFC.First();
400  if (power > _powerPatternFC.Last()) return _powerPatternFC.Last();
401 
402  return power;
403  }
404  #endregion
405 
406  #region GetEmission
407  public double GetEmission(string pollutant, double power, double speed, Helpers VehicleClass)
408  {
409  //Declaration
410  List<double> emissionCurve;
411  List<double> powerPattern;
412 
413  // bisection search to find correct position in power pattern
414  int upperIndex;
415  int lowerIndex;
416 
417  if (VehicleClass.tClass != Constants.strBEV)
418  {
419  if (Math.Abs(speed) <= Constants.ZERO_SPEED_ACCURACY)
420  {
421  if (pollutant == "FC")
422  {
423  return _idlingValueFC;
424  }
425  else
426  {
427  if (!_cepCurvePollutants.ContainsKey(pollutant))
428  {
429  VehicleClass.ErrMsg = "Emission pollutant " + pollutant + " not found!";
430  return 0;
431  }
432 
433  return _idlingValuesPollutants[pollutant];
434  }
435  }
436  }
437 
438  if (pollutant == "FC")
439  {
440  emissionCurve = _cepCurveFC;
441  powerPattern = _powerPatternFC;
442  }
443  else
444  {
445  if (!_cepCurvePollutants.ContainsKey(pollutant))
446  {
447  VehicleClass.ErrMsg = "Emission pollutant " + pollutant + " not found!";
448  return 0;
449  }
450 
451  emissionCurve = _cepCurvePollutants[pollutant];
452  powerPattern = _powerPatternPollutants;
453  }
454 
455  if (emissionCurve.Count == 0)
456  {
457  VehicleClass.ErrMsg = "Empty emission curve for " + pollutant + " found!";
458  return 0;
459  }
460  if (emissionCurve.Count == 1)
461  {
462  return emissionCurve[0];
463  }
464 
465  // in case that the demanded power is smaller than the first entry (smallest) in the power pattern the first is returned (should never happen)
466  if (power <= powerPattern.First())
467  {
468  return emissionCurve[0];
469  }
470 
471  // if power bigger than all entries in power pattern return the last (should never happen)
472  if (power >= powerPattern.Last())
473  {
474  return emissionCurve.Last();
475  }
476 
477  FindLowerUpperInPattern(out lowerIndex, out upperIndex, powerPattern, power);
478  return Interpolate(power, powerPattern[lowerIndex], powerPattern[upperIndex], emissionCurve[lowerIndex], emissionCurve[upperIndex]);
479  }
480  #endregion
481 
482  #if FLEET
483  #region GetNormedEmission
484  public double GetNormedEmission(string pollutant, double power, double speed, Helpers VehicleClass)
485  {
486  //Declaration
487  List<double> emissionCurve;
488  List<double> powerPattern;
489 
490  // bisection search to find correct position in power pattern
491  int upperIndex;
492  int lowerIndex;
493 
494  if (pollutant == "FC")
495  {
496  emissionCurve = _normedCepCurveFC;
497  powerPattern = _normalizedPowerPatternFC;
498  }
499  else
500  {
501  if (!_cepCurvePollutants.ContainsKey(pollutant))
502  {
503  VehicleClass.ErrMsg = "Emission pollutant " + pollutant + " not found!";
504  return 0;
505  }
506  emissionCurve = _cepNormalizedCurvePollutants[pollutant];
507  powerPattern = _normailzedPowerPatternPollutants;
508  }
509 
510  if (emissionCurve.Count == 0)
511  {
512  VehicleClass.ErrMsg = "Empty emission curve for " + pollutant + " found!";
513  return 0;
514  }
515  if (emissionCurve.Count == 1)
516  {
517  return emissionCurve[0];
518  }
519  // in case that the demanded power is smaller than the first entry (smallest) in the power pattern the first is returned (should never happen)
520  if (power <= powerPattern.First())
521  {
522  return emissionCurve[0];
523  }
524 
525  // if power bigger than all entries in power pattern the last is returned (should never happen)
526  if (power >= powerPattern.Last())
527  {
528  return emissionCurve.Last();
529  }
530 
531  FindLowerUpperInPattern(out lowerIndex, out upperIndex, powerPattern, power);
532  return Interpolate(power, powerPattern[lowerIndex], powerPattern[upperIndex], emissionCurve[lowerIndex], emissionCurve[upperIndex]);
533  }
534  #endregion
535  #endif
536 
537  #region GetCO2Emission
538  public double GetCO2Emission(double _FC, double _CO, double _HC, Helpers VehicleClass)
539  {
540  //Declaration
541  double fCBr;
542  double fCHC = 0.866;
543  double fCCO = 0.429;
544  double fCCO2 = 0.273;
545 
546  switch (_fuelType)
547  {
548  case Constants.strGasoline:
549  fCBr = 0.865;
550  break;
551  case Constants.strDiesel:
552  fCBr = 0.863;
553  break;
554  case Constants.strCNG:
555  fCBr = 0.693;
556  fCHC = 0.803;
557  break;
558  default:
559  VehicleClass.ErrMsg = "The propolsion type is not known! (" + _fuelType + ")";
560  return 0;
561  }
562 
563  return (_FC * fCBr - _CO * fCCO - _HC * fCHC) / fCCO2;
564  }
565  #endregion
566 
567  #region GetDecelCoast
568  public double GetDecelCoast(double speed, double acc, double gradient)
569  {
570  //Declaration
571  int upperIndex;
572  int lowerIndex;
573 
574  if (speed < Constants.SPEED_DCEL_MIN)
575  {
576  return speed / Constants.SPEED_DCEL_MIN * GetDecelCoast(Constants.SPEED_DCEL_MIN, acc, gradient);
577  }
578 
579  double rotCoeff = GetRotationalCoeffecient(speed);
580  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _speedPatternRotational, speed);
581  double iGear = Interpolate(speed,
582  _speedPatternRotational[lowerIndex],
583  _speedPatternRotational[upperIndex],
584  _gearTransmissionCurve[lowerIndex],
585  _gearTransmissionCurve[upperIndex]);
586 
587  double iTot = iGear * _axleRatio;
588 
589  double n = (30 * speed * iTot) / ((_effectiveWheelDiameter / 2) * Math.PI);
590  double nNorm = (n - _engineIdlingSpeed) / (_engineRatedSpeed - _engineIdlingSpeed);
591 
592  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _nNormTable, nNorm);
593 
594  double fMot = 0;
595 
596  if (speed >= 10e-2)
597  {
598  fMot = (-Interpolate(nNorm,
599  _nNormTable[lowerIndex],
600  _nNormTable[upperIndex],
601  _dragNormTable[lowerIndex],
602  _dragNormTable[upperIndex]) * _ratedPower * 1000 / speed) / 0.9;
603  }
604 
605  double fRoll = (_resistanceF0
606  + _resistanceF1 * speed
607  + Math.Pow(_resistanceF2 * speed, 2)
608  + Math.Pow(_resistanceF3 * speed, 3)
609  + Math.Pow(_resistanceF4 * speed, 4)) * (_massVehicle + _vehicleLoading) * Constants.GRAVITY_CONST;
610 
611  double fAir = _cWValue * _crossSectionalArea * 1.2 * 0.5 * Math.Pow(speed, 2);
612 
613  double fGrad = (_massVehicle + _vehicleLoading) * Constants.GRAVITY_CONST * gradient / 100;
614 
615  return -(fMot + fRoll + fAir + fGrad) / ((_massVehicle + _vehicleLoading) * rotCoeff);
616  }
617  #endregion
618 
619  #region GetRotationalCoeffecient
620  public double GetRotationalCoeffecient(double speed)
621  {
622  //Declaration
623  int upperIndex;
624  int lowerIndex;
625 
626  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _speedPatternRotational, speed);
627  return Interpolate(speed,
628  _speedPatternRotational[lowerIndex],
629  _speedPatternRotational[upperIndex],
630  _speedCurveRotational[lowerIndex],
631  _speedCurveRotational[upperIndex]);
632  }
633  #endregion
634 
635  #if FLEET
636  #region GetGearCoeffecient
637  public double GetGearCoeffecient(double speed)
638  {
639  //Declaration
640  int upperIndex;
641  int lowerIndex;
642 
643  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _speedPatternRotational, speed);
644  return Interpolate(speed,
645  _speedPatternRotational[lowerIndex],
646  _speedPatternRotational[upperIndex],
647  _gearTransmissionCurve[lowerIndex],
648  _gearTransmissionCurve[upperIndex]);
649  }
650  #endregion
651 
652  #region GetDragCoeffecient
653  public double GetDragCoeffecient(double nNorm)
654  {
655  //Declaration
656  int upperIndex;
657  int lowerIndex;
658 
659  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _nNormTable, nNorm);
660  return Interpolate(nNorm,
661  _nNormTable[lowerIndex],
662  _nNormTable[upperIndex],
663  _dragNormTable[lowerIndex],
664  _dragNormTable[upperIndex]);
665  }
666  #endregion
667  #endif
668 
669  #region FindLowerUpperInPattern
670  private void FindLowerUpperInPattern(out int lowerIndex, out int upperIndex, List<double> pattern, double value)
671  {
672  lowerIndex = 0;
673  upperIndex = 0;
674 
675  if (value <= pattern.First())
676  {
677  lowerIndex = 0;
678  upperIndex = 0;
679  return;
680  }
681 
682  if (value >= pattern.Last())
683  {
684  lowerIndex = pattern.Count - 1;
685  upperIndex = pattern.Count - 1;
686  return;
687  }
688 
689  // bisection search to find correct position in power pattern
690  int middleIndex = (pattern.Count - 1) / 2;
691  upperIndex = pattern.Count - 1;
692  lowerIndex = 0;
693 
694  while (upperIndex - lowerIndex > 1)
695  {
696  if (pattern[middleIndex] == value)
697  {
698  lowerIndex = middleIndex;
699  upperIndex = middleIndex;
700  return;
701  }
702  else if (pattern[middleIndex] < value)
703  {
704  lowerIndex = middleIndex;
705  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
706  }
707  else
708  {
709  upperIndex = middleIndex;
710  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
711  }
712  }
713 
714  if (pattern[lowerIndex] <= value && value < pattern[upperIndex])
715  {
716  return;
717  }
718  }
719  #endregion
720 
721  #region Interpolate
722  private double Interpolate(double px, double p1, double p2, double e1, double e2)
723  {
724  if (p2 == p1)
725  return e1;
726 
727  return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
728  }
729  #endregion
730 
731  //--------------------------------------------------------------------------------------------------
732  // Operators for fleetmix
733  //--------------------------------------------------------------------------------------------------
734 
735  #if FLEET
736  #region AddRangeCeps
737  public static CEP AddRangeCeps(CEP[] cps, Helpers Helper)
738  {
739  #region SingleValues
740  CEP newCEP = new CEP(cps.Select(p => p.HeavyVehicle ? 1 : 0).Sum() > 0,
741  cps.Select(p => p._massVehicle).Sum(),
742  cps.Select(p => p._vehicleLoading).Sum(),
743  cps.Select(p => p._vehicleMassRot).Sum(),
744  cps.Select(p => p._crossSectionalArea).Sum(),
745  cps.Select(p => p._cWValue).Sum(),
746  cps.Select(p => p._resistanceF0).Sum(),
747  cps.Select(p => p._resistanceF1).Sum(),
748  cps.Select(p => p._resistanceF2).Sum(),
749  cps.Select(p => p._resistanceF3).Sum(),
750  cps.Select(p => p._resistanceF4).Sum(),
751  cps.Select(p => p._axleRatio).Sum(),
752  cps.Select(p => p._auxPower).Sum(),
753  cps.Select(p => p._ratedPower).Sum(),
754  cps.Select(p => p._engineIdlingSpeed).Sum(),
755  cps.Select(p => p._engineRatedSpeed).Sum(),
756  cps.Select(p => p._effectiveWheelDiameter).Sum(),
757  cps.Select(p => p._pNormV0).Sum(),
758  cps.Select(p => p._pNormP0).Sum(),
759  cps.Select(p => p._pNormV1).Sum(),
760  cps.Select(p => p._pNormP1).Sum());
761 
762  newCEP._fuelType = cps.First().FuelType;
763  #endregion
764 
765  #region SpeedRotationalTable
766  double minSpeedRotational = cps.Select(p => p._speedPatternRotational.First()).Min();
767  double maxSpeedRotational = cps.Select(p => p._speedPatternRotational.Last()).Max();
768 
769  newCEP._speedPatternRotational
770  = CreatePattern(minSpeedRotational,
771  maxSpeedRotational,
773 
774  newCEP._speedCurveRotational = new List<double>();
775  newCEP._gearTransmissionCurve = new List<double>();
776 
777  for (int i = 0; i < newCEP._speedPatternRotational.Count; i++)
778  {
779  newCEP._speedCurveRotational.Add(cps.Select(p => p.GetRotationalCoeffecient(newCEP._speedPatternRotational[i])).Sum());
780 
781  newCEP._gearTransmissionCurve.Add(cps.Select(p => p.GetGearCoeffecient(newCEP._speedPatternRotational[i])).Sum());
782  }
783  #endregion
784 
785  #region NormalizingPower
786  newCEP._drivingPower = newCEP.CalcPower(Constants.NORMALIZING_SPEED, Constants.NORMALIZING_ACCELARATION, 0);
787 
788  if (newCEP._heavyVehicle)
789  {
790  newCEP._normalizingPower = newCEP._ratedPower;
791  newCEP._normalizingType = NormalizingType.RatedPower;
792  }
793  else
794  {
795  newCEP._normalizingPower = newCEP._drivingPower;
796  newCEP._normalizingType = NormalizingType.DrivingPower;
797  }
798  #endregion
799 
800  #region FC
801  double minNormPowerPatternFC = cps.Select(p => p._normalizedPowerPatternFC.First()).Min();
802  double maxNormPowerPatternFC = cps.Select(p => p._normalizedPowerPatternFC.Last()).Max();
803 
804  newCEP._normalizedPowerPatternFC
805  = CreatePattern(minNormPowerPatternFC,
806  maxNormPowerPatternFC,
808 
809  newCEP._cepCurveFC = new List<double>();
810  newCEP._normedCepCurveFC = new List<double>();
811  newCEP._powerPatternFC = new List<double>();
812 
813  for (int i = 0; i < newCEP._normalizedPowerPatternFC.Count; i++)
814  {
815  double newCepVal = cps.Select(p => p.GetNormedEmission("FC", newCEP._normalizedPowerPatternFC[i], double.MaxValue, Helper)).Sum();
816  newCEP._cepCurveFC.Add(newCepVal * newCEP._ratedPower);
817  newCEP._normedCepCurveFC.Add(newCepVal);
818  newCEP._powerPatternFC.Add(newCEP._normalizedPowerPatternFC[i] * newCEP._ratedPower);
819  }
820  #endregion
821 
822  #region Pollutants
823  double minNormPowerPattern = cps.Select(p => p._normailzedPowerPatternPollutants.First()).Min();
824  double maxNormPowerPattern = cps.Select(p => p._normailzedPowerPatternPollutants.Last()).Max();
825 
826  newCEP._normailzedPowerPatternPollutants
827  = CreatePattern(minNormPowerPattern,
828  maxNormPowerPattern,
830 
831  newCEP._cepCurvePollutants = new Dictionary<string, List<double>>();
832  newCEP._powerPatternPollutants = new List<double>();
833  newCEP._cepNormalizedCurvePollutants = new Dictionary<string, List<double>>();
834 
835  foreach (string id in cps.First()._cepCurvePollutants.Keys)
836  {
837  newCEP._cepCurvePollutants.Add(id, new List<double>());
838  newCEP._cepNormalizedCurvePollutants.Add(id, new List<double>());
839  }
840 
841  for (int i = 0; i < newCEP._normailzedPowerPatternPollutants.Count; i++)
842  {
843  foreach (string id in newCEP._cepCurvePollutants.Keys)
844  {
845  if (newCEP.NormalizingTypeX == NormalizingType.RatedPower)
846  {
847  double newCepVal = cps.Select(p => p.GetNormedEmission(id, newCEP._normailzedPowerPatternPollutants[i], double.MaxValue, Helper)).Sum();
848  newCEP._cepCurvePollutants[id].Add(newCepVal * newCEP._ratedPower);
849  newCEP._cepNormalizedCurvePollutants[id].Add(newCepVal);
850  }
851  else
852  {
853  newCEP._cepCurvePollutants[id].Add(cps.Select(p => p.GetEmission(id, newCEP._normailzedPowerPatternPollutants[i] * p._normalizingPower, double.MaxValue, Helper)).Sum());
854  newCEP._cepNormalizedCurvePollutants[id].Add(cps.Select(p => p.GetNormedEmission(id, newCEP._normailzedPowerPatternPollutants[i], double.MaxValue, Helper)).Sum());
855  }
856  }
857  newCEP._powerPatternPollutants.Add(newCEP._normailzedPowerPatternPollutants[i] * newCEP.NormalizingPower);
858  }
859  #endregion
860 
861  #region IdlingValues
862  newCEP._idlingValueFC = cps.Select(p => p._idlingValueFC).Sum();
863  newCEP._idlingValuesPollutants = new Dictionary<string, double>();
864 
865  foreach (string id in cps.First()._idlingValuesPollutants.Keys)
866  {
867  newCEP._idlingValuesPollutants.Add(id, cps.Select(p => p._idlingValuesPollutants[id]).Sum());
868  }
869  #endregion
870 
871  #region TragTable
872  double minTragTable = cps.Select(p => p._nNormTable.First()).Min();
873  double maxTragTable = cps.Select(p => p._nNormTable.Last()).Max();
874 
875  newCEP._nNormTable
876  = CreatePattern(minTragTable,
877  maxTragTable,
879 
880  newCEP._dragNormTable = new List<double>();
881 
882  for (int i = 0; i < newCEP._nNormTable.Count; i++)
883  {
884  newCEP._dragNormTable.Add(cps.Select(p => p.GetDragCoeffecient(newCEP._nNormTable[i])).Sum());
885  }
886  #endregion
887  return newCEP;
888  }
889  #endregion
890 
891  #region Operator *
892  public static CEP operator *(CEP cp1, double d)
893  {
894  #region SingleValues
895  CEP newCEP = new CEP(cp1.HeavyVehicle,
896  d * cp1._massVehicle,
897  d * cp1._vehicleLoading,
898  d * cp1._vehicleMassRot,
899  d * cp1._crossSectionalArea,
900  d * cp1._cWValue,
901  d * cp1._resistanceF0,
902  d * cp1._resistanceF1,
903  d * cp1._resistanceF2,
904  d * cp1._resistanceF3,
905  d * cp1._resistanceF4,
906  d * cp1._axleRatio,
907  d * cp1._auxPower,
908  d * cp1._ratedPower,
909  d * cp1._engineIdlingSpeed,
910  d * cp1._engineRatedSpeed,
911  d * cp1._effectiveWheelDiameter,
912  d * cp1._pNormV0,
913  d * cp1._pNormP0,
914  d * cp1._pNormV1,
915  d * cp1._pNormP1);
916 
917  newCEP._fuelType = cp1.FuelType;
918  #endregion
919 
920  #region SpeedRotationalTable
921  newCEP._speedPatternRotational = new List<double>(cp1._speedPatternRotational);
922  newCEP._speedCurveRotational = new List<double>(cp1._speedCurveRotational.Select(p => p * d));
923  newCEP._gearTransmissionCurve = new List<double>(cp1._gearTransmissionCurve.Select(p => p * d));
924  #endregion
925 
926  #region NormalizingPower
927  newCEP._drivingPower = newCEP.CalcPower(Constants.NORMALIZING_SPEED, Constants.NORMALIZING_ACCELARATION, 0);
928 
929  if (newCEP._heavyVehicle)
930  {
931  newCEP._normalizingPower = newCEP._ratedPower;
932  newCEP._normalizingType = NormalizingType.RatedPower;
933  }
934  else
935  {
936  newCEP._normalizingPower = newCEP._drivingPower;
937  newCEP._normalizingType = NormalizingType.DrivingPower;
938  }
939  #endregion
940 
941  #region FC
942  newCEP._powerPatternFC = new List<double>(cp1._powerPatternFC.Select(p => p * d));
943  newCEP._normalizedPowerPatternFC = new List<double>(cp1._normalizedPowerPatternFC);
944  newCEP._cepCurveFC = new List<double>(cp1._cepCurveFC.Select(p => p * d));
945  newCEP._normedCepCurveFC = new List<double>(cp1._normedCepCurveFC.Select(p => p * d));
946  #endregion
947 
948  #region Pollutants
949  newCEP._powerPatternPollutants = new List<double>(cp1._normailzedPowerPatternPollutants.Select(p => p * newCEP._normalizingPower));
950  newCEP._normailzedPowerPatternPollutants = new List<double>(cp1._normailzedPowerPatternPollutants);
951  newCEP._cepCurvePollutants = new Dictionary<string, List<double>>();
952  newCEP._cepNormalizedCurvePollutants = new Dictionary<string, List<double>>();
953 
954  foreach (string id in cp1._cepCurvePollutants.Keys)
955  {
956  newCEP._cepCurvePollutants.Add(id, new List<double>(cp1._cepCurvePollutants[id].Select(p => p * d)));
957  newCEP._cepNormalizedCurvePollutants.Add(id, new List<double>(cp1._cepNormalizedCurvePollutants[id].Select(p => p * d)));
958  }
959  #endregion
960 
961  #region IdlingValues
962  newCEP._idlingValueFC = cp1._idlingValueFC * d;
963  newCEP._idlingValuesPollutants = new Dictionary<string, double>();
964 
965  foreach (string id in cp1._idlingValuesPollutants.Keys)
966  {
967  newCEP._idlingValuesPollutants.Add(id,
968  cp1._idlingValuesPollutants[id] * d);
969  }
970  #endregion
971 
972  #region DragTable
973  newCEP._nNormTable = new List<double>(cp1._nNormTable);
974  newCEP._dragNormTable = new List<double>(cp1._dragNormTable.Select(p => p * d));
975  #endregion
976  return newCEP;
977  }
978  #endregion
979 
980  #region CreatePattern
981  static public List<double> CreatePattern(double min, double max, double increment)
982  {
983  //Declaration
984  List<double> pattern = new List<double>();
985  double actualMin = min;
986  double actualMax = max;
987 
988  if (min < 0)
989  actualMin = Math.Ceiling(min / increment) * increment;
990  else
991  actualMin = Math.Floor(min / increment) * increment;
992 
993  if (max < 0)
994  actualMax = Math.Floor(max / increment) * increment;
995  else
996  actualMax = Math.Ceiling(max / increment) * increment;
997 
998  double curVal = actualMin;
999 
1000  while (curVal <= actualMax)
1001  {
1002  pattern.Add(curVal);
1003  curVal += increment;
1004  }
1005  return pattern;
1006  }
1007  #endregion
1008  #endif
1009  }
1010 }
List< double > _normalizedPowerPatternFC
Definition: CEP.cs:352
List< double > _cepCurveFC
Definition: CEP.cs:356
std::vector< double > _speedPatternRotational
Definition: CEP.h:90
double _resistanceF0
Definition: CEP.h:74
List< double > _normedCepCurveFC
Definition: CEP.cs:357
static const double SPEED_DCEL_MIN
Definition: Constants.h:16
static const std::string strCNG
Definition: Constants.h:39
List< double > _speedPatternRotational
Definition: CEP.cs:350
const double SPEED_ROTATIONAL_INCREMENT
Definition: Constants.cs:24
const double POWER_FC_INCREMENT
Definition: Constants.cs:25
Dictionary< string, List< double > > _cepNormalizedCurvePollutants
Definition: CEP.cs:361
#define min(a, b)
Definition: polyfonts.c:66
double GetEmission(string pollutant, double power, double speed, Helpers VehicleClass)
Definition: CEP.cs:407
List< double > _powerPatternPollutants
Definition: CEP.cs:354
double NormalizingPower
Definition: CEP.cs:303
std::vector< double > _normailzedPowerPatternPollutants
Definition: CEP.h:93
std::vector< double > _dragNormTable
Definition: CEP.h:106
double _massVehicle
Definition: CEP.h:69
std::map< std::string, std::vector< double > > _cepCurvePollutants
Definition: CEP.h:100
double _effectiveWheelDiameter
Definition: CEP.h:88
std::vector< double > _nNormTable
Definition: CEP.h:105
List< double > _nNormTable
Definition: CEP.cs:365
double DrivingPower
Definition: CEP.cs:314
double GetDragCoeffecient(double nNorm)
Definition: CEP.cs:653
double _pNormP0
Definition: CEP.h:82
double _engineRatedSpeed
Definition: CEP.h:86
static CEP AddRangeCeps(CEP[] cps, Helpers Helper)
Definition: CEP.cs:737
List< double > _gearTransmissionCurve
Definition: CEP.cs:358
const double NNORM_INCREMENT
Definition: Constants.cs:27
double GetGearCoeffecient(double speed)
Definition: CEP.cs:637
double _pNormV1
Definition: CEP.h:83
double _drivingPower
Definition: CEP.h:61
double _resistanceF1
Definition: CEP.h:75
CEP(bool heavyVehicle, double vehicleMass, double vehicleLoading, double vehicleMassRot, double crossArea, double cWValue, double f0, double f1, double f2, double f3, double f4, double axleRatio, List< double > transmissionGearRatios, double auxPower, double ratedPower, double engineIdlingSpeed, double engineRatedSpeed, double effictiveWheelDiameter, double pNormV0, double pNormP0, double pNormV1, double pNormP1, string vehicelFuelType, List< List< double >> matrixFC, List< string > headerLinePollutants, List< List< double >> matrixPollutants, List< List< double >> matrixSpeedRotational, List< List< double >> normedDragTable, double idlingFC, List< double > idlingPollutants)
Definition: CEP.cs:17
#define Min
Definition: RTree.h:14
Dictionary< string, double > _idlingValuesPollutants
Definition: CEP.cs:363
static CEP operator*(CEP cp1, double d)
Definition: CEP.cs:892
List< double > _powerPatternFC
Definition: CEP.cs:351
#define Max
Definition: RTree.h:17
double GetRotationalCoeffecient(double speed)
Definition: CEP.cpp:331
#define max(a, b)
Definition: polyfonts.c:65
bool HeavyVehicle
Definition: CEP.cs:250
double _auxPower
Definition: CEP.h:80
double _engineIdlingSpeed
Definition: CEP.h:87
std::map< std::string, double > _idlingValuesPollutants
Definition: CEP.h:103
double _resistanceF2
Definition: CEP.h:76
std::vector< double > _normedCepCurveFC
Definition: CEP.h:97
static const double NORMALIZING_SPEED
Definition: Constants.h:14
Dictionary< string, List< double > > _cepCurvePollutants
Definition: CEP.cs:360
NormalizingType _normalizingType
Definition: CEP.h:45
double _pNormP1
Definition: CEP.h:84
std::map< std::string, std::vector< double > > _cepNormalizedCurvePollutants
Definition: CEP.h:101
double _normalizingPower
Definition: CEP.h:56
List< double > _normailzedPowerPatternPollutants
Definition: CEP.cs:353
std::vector< double > _normalizedPowerPatternFC
Definition: CEP.h:92
static const double NORMALIZING_ACCELARATION
Definition: Constants.h:15
double _cWValue
Definition: CEP.h:73
static const std::string strDiesel
Definition: Constants.h:38
double GetDecelCoast(double speed, double acc, double gradient)
Definition: CEP.cs:568
NormalizingType NormalizingTypeX
Definition: CEP.cs:277
double RatedPower
Definition: CEP.cs:288
double CalcEngPower(double power)
Definition: CEP.cs:397
List< double > _dragNormTable
Definition: CEP.cs:366
bool _heavyVehicle
Definition: CEP.h:30
double GetNormedEmission(string pollutant, double power, double speed, Helpers VehicleClass)
Definition: CEP.cs:484
const double POWER_POLLUTANT_INCREMENT
Definition: Constants.cs:26
double _resistanceF4
Definition: CEP.h:78
std::vector< double > _speedCurveRotational
Definition: CEP.h:99
std::vector< double > _gearTransmissionCurve
Definition: CEP.h:98
static const std::string strGasoline
Definition: Constants.h:37
void FindLowerUpperInPattern(out int lowerIndex, out int upperIndex, List< double > pattern, double value)
Definition: CEP.cs:670
static List< double > CreatePattern(double min, double max, double increment)
Definition: CEP.cs:981
double _pNormV0
Definition: CEP.h:81
double _resistanceF3
Definition: CEP.h:77
string _fuelType
Definition: CEP.cs:259
CEP(bool heavyVehicle, double vehicleMass, double vehicleLoading, double vehicleMassRot, double crossArea, double cWValue, double f0, double f1, double f2, double f3, double f4, double axleRatio, std::vector< double > &transmissionGearRatios, double auxPower, double ratedPower, double engineIdlingSpeed, double engineRatedSpeed, double effictiveWheelDiameter, double pNormV0, double pNormP0, double pNormV1, double pNormP1, const std::string &vehicelFuelType, std::vector< std::vector< double > > &matrixFC, std::vector< std::string > &headerLinePollutants, std::vector< std::vector< double > > &matrixPollutants, std::vector< std::vector< double > > &matrixSpeedRotational, std::vector< std::vector< double > > &normedDragTable, double idlingFC, std::vector< double > &idlingPollutants)
Definition: CEP.cpp:8
std::vector< double > _powerPatternFC
Definition: CEP.h:91
List< double > _speedCurveRotational
Definition: CEP.cs:359
std::vector< double > _cepCurveFC
Definition: CEP.h:96
static const std::string strBEV
Definition: Constants.h:41
double Interpolate(double px, double p1, double p2, double e1, double e2)
Definition: CEP.cpp:382
static const double GRAVITY_CONST
Definition: Constants.h:12
double GetCO2Emission(double _FC, double _CO, double _HC, Helpers VehicleClass)
Definition: CEP.cs:538
CEP(bool heavyVehicle, double vehicleMass, double vehicleLoading, double vehicleMassRot, double crossArea, double cWValue, double f0, double f1, double f2, double f3, double f4, double axleRatio, double auxPower, double ratedPower, double engineIdlingSpeed, double engineRatedSpeed, double effictiveWheelDiameter, double pNormV0, double pNormP0, double pNormV1, double pNormP1)
Definition: CEP.cs:192
string FuelType
Definition: CEP.cs:261
double _axleRatio
Definition: CEP.h:79
double _crossSectionalArea
Definition: CEP.h:72
std::vector< double > _powerPatternPollutants
Definition: CEP.h:94
static double _DRIVE_TRAIN_EFFICIENCY
Definition: Constants.h:53
double _idlingValueFC
Definition: CEP.h:102
static const double ZERO_SPEED_ACCURACY
Definition: Constants.h:17
double CalcPower(double speed, double acc, double gradient)
Definition: CEP.cpp:175
double _vehicleLoading
Definition: CEP.h:70
static const double AIR_DENSITY_CONST
Definition: Constants.h:13
double _ratedPower
Definition: CEP.h:50
void FindLowerUpperInPattern(int &lowerIndex, int &upperIndex, std::vector< double > &pattern, double value)
Definition: CEP.cpp:340
std::string _fuelType
Definition: CEP.h:35
double _vehicleMassRot
Definition: CEP.h:71