Eclipse SUMO - Simulation of Urban MObility
dll_code/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  case Constants.strLPG:
559  fCBr = 0.825;
560  fCHC = 0.825;
561  break;
562  default:
563  VehicleClass.ErrMsg = "The propolsion type is not known! (" + _fuelType + ")";
564  return 0;
565  }
566 
567  return (_FC * fCBr - _CO * fCCO - _HC * fCHC) / fCCO2;
568  }
569  #endregion
570 
571  #region GetDecelCoast
572  public double GetDecelCoast(double speed, double acc, double gradient)
573  {
574  //Declaration
575  int upperIndex;
576  int lowerIndex;
577 
578  if (speed < Constants.SPEED_DCEL_MIN)
579  {
580  return speed / Constants.SPEED_DCEL_MIN * GetDecelCoast(Constants.SPEED_DCEL_MIN, acc, gradient);
581  }
582 
583  double rotCoeff = GetRotationalCoeffecient(speed);
584  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _speedPatternRotational, speed);
585  double iGear = Interpolate(speed,
586  _speedPatternRotational[lowerIndex],
587  _speedPatternRotational[upperIndex],
588  _gearTransmissionCurve[lowerIndex],
589  _gearTransmissionCurve[upperIndex]);
590 
591  double iTot = iGear * _axleRatio;
592 
593  double n = (30 * speed * iTot) / ((_effectiveWheelDiameter / 2) * Math.PI);
594  double nNorm = (n - _engineIdlingSpeed) / (_engineRatedSpeed - _engineIdlingSpeed);
595 
596  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _nNormTable, nNorm);
597 
598  double fMot = 0;
599 
600  if (speed >= 10e-2)
601  {
602  fMot = (-Interpolate(nNorm,
603  _nNormTable[lowerIndex],
604  _nNormTable[upperIndex],
605  _dragNormTable[lowerIndex],
606  _dragNormTable[upperIndex]) * _ratedPower * 1000 / speed) / 0.9;
607  }
608 
609  double fRoll = (_resistanceF0
610  + _resistanceF1 * speed
611  + Math.Pow(_resistanceF2 * speed, 2)
612  + Math.Pow(_resistanceF3 * speed, 3)
613  + Math.Pow(_resistanceF4 * speed, 4)) * (_massVehicle + _vehicleLoading) * Constants.GRAVITY_CONST;
614 
615  double fAir = _cWValue * _crossSectionalArea * 1.2 * 0.5 * Math.Pow(speed, 2);
616 
617  double fGrad = (_massVehicle + _vehicleLoading) * Constants.GRAVITY_CONST * gradient / 100;
618 
619  return -(fMot + fRoll + fAir + fGrad) / ((_massVehicle + _vehicleLoading) * rotCoeff);
620  }
621  #endregion
622 
623  #region GetRotationalCoeffecient
624  public double GetRotationalCoeffecient(double speed)
625  {
626  //Declaration
627  int upperIndex;
628  int lowerIndex;
629 
630  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _speedPatternRotational, speed);
631  return Interpolate(speed,
632  _speedPatternRotational[lowerIndex],
633  _speedPatternRotational[upperIndex],
634  _speedCurveRotational[lowerIndex],
635  _speedCurveRotational[upperIndex]);
636  }
637  #endregion
638 
639  #if FLEET
640  #region GetGearCoeffecient
641  public double GetGearCoeffecient(double speed)
642  {
643  //Declaration
644  int upperIndex;
645  int lowerIndex;
646 
647  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _speedPatternRotational, speed);
648  return Interpolate(speed,
649  _speedPatternRotational[lowerIndex],
650  _speedPatternRotational[upperIndex],
651  _gearTransmissionCurve[lowerIndex],
652  _gearTransmissionCurve[upperIndex]);
653  }
654  #endregion
655 
656  #region GetDragCoeffecient
657  public double GetDragCoeffecient(double nNorm)
658  {
659  //Declaration
660  int upperIndex;
661  int lowerIndex;
662 
663  FindLowerUpperInPattern(out lowerIndex, out upperIndex, _nNormTable, nNorm);
664  return Interpolate(nNorm,
665  _nNormTable[lowerIndex],
666  _nNormTable[upperIndex],
667  _dragNormTable[lowerIndex],
668  _dragNormTable[upperIndex]);
669  }
670  #endregion
671  #endif
672 
673  #region FindLowerUpperInPattern
674  private void FindLowerUpperInPattern(out int lowerIndex, out int upperIndex, List<double> pattern, double value)
675  {
676  lowerIndex = 0;
677  upperIndex = 0;
678 
679  if (value <= pattern.First())
680  {
681  lowerIndex = 0;
682  upperIndex = 0;
683  return;
684  }
685 
686  if (value >= pattern.Last())
687  {
688  lowerIndex = pattern.Count - 1;
689  upperIndex = pattern.Count - 1;
690  return;
691  }
692 
693  // bisection search to find correct position in power pattern
694  int middleIndex = (pattern.Count - 1) / 2;
695  upperIndex = pattern.Count - 1;
696  lowerIndex = 0;
697 
698  while (upperIndex - lowerIndex > 1)
699  {
700  if (pattern[middleIndex] == value)
701  {
702  lowerIndex = middleIndex;
703  upperIndex = middleIndex;
704  return;
705  }
706  else if (pattern[middleIndex] < value)
707  {
708  lowerIndex = middleIndex;
709  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
710  }
711  else
712  {
713  upperIndex = middleIndex;
714  middleIndex = (upperIndex - lowerIndex) / 2 + lowerIndex;
715  }
716  }
717 
718  if (pattern[lowerIndex] <= value && value < pattern[upperIndex])
719  {
720  return;
721  }
722  }
723  #endregion
724 
725  #region Interpolate
726  private double Interpolate(double px, double p1, double p2, double e1, double e2)
727  {
728  if (p2 == p1)
729  return e1;
730 
731  return e1 + (px - p1) / (p2 - p1) * (e2 - e1);
732  }
733  #endregion
734 
735  #region GetMaxAccel
736  public double GetMaxAccel(double speed, double gradient)
737  {
738  double rotFactor = GetRotationalCoeffecient(speed);
739  double pMaxForAcc = GetPMaxNorm(speed) * _ratedPower - CalcPower(speed, 0, gradient);
740 
741  return (pMaxForAcc * 1000) / ((_massVehicle * rotFactor + _vehicleMassRot + _vehicleLoading) * speed);
742  }
743  #endregion
744 
745  #region GetPMaxNorm
746  private double GetPMaxNorm(double speed)
747  {
748  // Linear function between v0 and v1, constant elsewhere
749  if (speed <= _pNormV0)
750  return _pNormP0;
751  else if (speed >= _pNormV1)
752  return _pNormP1;
753  else
754  {
755  return Interpolate(speed, _pNormV0, _pNormV1, _pNormP0, _pNormP1);
756  }
757  }
758  #endregion
759 
760  //--------------------------------------------------------------------------------------------------
761  // Operators for fleetmix
762  //--------------------------------------------------------------------------------------------------
763 
764  #if FLEET
765  #region AddRangeCeps
766  public static CEP AddRangeCeps(CEP[] cps, Helpers Helper)
767  {
768  #region SingleValues
769  CEP newCEP = new CEP(cps.Select(p => p.HeavyVehicle ? 1 : 0).Sum() > 0,
770  cps.Select(p => p._massVehicle).Sum(),
771  cps.Select(p => p._vehicleLoading).Sum(),
772  cps.Select(p => p._vehicleMassRot).Sum(),
773  cps.Select(p => p._crossSectionalArea).Sum(),
774  cps.Select(p => p._cWValue).Sum(),
775  cps.Select(p => p._resistanceF0).Sum(),
776  cps.Select(p => p._resistanceF1).Sum(),
777  cps.Select(p => p._resistanceF2).Sum(),
778  cps.Select(p => p._resistanceF3).Sum(),
779  cps.Select(p => p._resistanceF4).Sum(),
780  cps.Select(p => p._axleRatio).Sum(),
781  cps.Select(p => p._auxPower).Sum(),
782  cps.Select(p => p._ratedPower).Sum(),
783  cps.Select(p => p._engineIdlingSpeed).Sum(),
784  cps.Select(p => p._engineRatedSpeed).Sum(),
785  cps.Select(p => p._effectiveWheelDiameter).Sum(),
786  cps.Select(p => p._pNormV0).Sum(),
787  cps.Select(p => p._pNormP0).Sum(),
788  cps.Select(p => p._pNormV1).Sum(),
789  cps.Select(p => p._pNormP1).Sum());
790 
791  newCEP._fuelType = cps.First().FuelType;
792  #endregion
793 
794  #region SpeedRotationalTable
795  double minSpeedRotational = cps.Select(p => p._speedPatternRotational.First()).Min();
796  double maxSpeedRotational = cps.Select(p => p._speedPatternRotational.Last()).Max();
797 
798  newCEP._speedPatternRotational
799  = CreatePattern(minSpeedRotational,
800  maxSpeedRotational,
802 
803  newCEP._speedCurveRotational = new List<double>();
804  newCEP._gearTransmissionCurve = new List<double>();
805 
806  for (int i = 0; i < newCEP._speedPatternRotational.Count; i++)
807  {
808  newCEP._speedCurveRotational.Add(cps.Select(p => p.GetRotationalCoeffecient(newCEP._speedPatternRotational[i])).Sum());
809 
810  newCEP._gearTransmissionCurve.Add(cps.Select(p => p.GetGearCoeffecient(newCEP._speedPatternRotational[i])).Sum());
811  }
812  #endregion
813 
814  #region NormalizingPower
815  newCEP._drivingPower = newCEP.CalcPower(Constants.NORMALIZING_SPEED, Constants.NORMALIZING_ACCELARATION, 0);
816 
817  if (newCEP._heavyVehicle)
818  {
819  newCEP._normalizingPower = newCEP._ratedPower;
820  newCEP._normalizingType = NormalizingType.RatedPower;
821  }
822  else
823  {
824  newCEP._normalizingPower = newCEP._drivingPower;
825  newCEP._normalizingType = NormalizingType.DrivingPower;
826  }
827  #endregion
828 
829  #region FC
830  double minNormPowerPatternFC = cps.Select(p => p._normalizedPowerPatternFC.First()).Min();
831  double maxNormPowerPatternFC = cps.Select(p => p._normalizedPowerPatternFC.Last()).Max();
832 
833  newCEP._normalizedPowerPatternFC
834  = CreatePattern(minNormPowerPatternFC,
835  maxNormPowerPatternFC,
837 
838  newCEP._cepCurveFC = new List<double>();
839  newCEP._normedCepCurveFC = new List<double>();
840  newCEP._powerPatternFC = new List<double>();
841 
842  for (int i = 0; i < newCEP._normalizedPowerPatternFC.Count; i++)
843  {
844  double newCepVal = cps.Select(p => p.GetNormedEmission("FC", newCEP._normalizedPowerPatternFC[i], double.MaxValue, Helper)).Sum();
845  newCEP._cepCurveFC.Add(newCepVal * newCEP._ratedPower);
846  newCEP._normedCepCurveFC.Add(newCepVal);
847  newCEP._powerPatternFC.Add(newCEP._normalizedPowerPatternFC[i] * newCEP._ratedPower);
848  }
849  #endregion
850 
851  #region Pollutants
852  double minNormPowerPattern = cps.Select(p => p._normailzedPowerPatternPollutants.First()).Min();
853  double maxNormPowerPattern = cps.Select(p => p._normailzedPowerPatternPollutants.Last()).Max();
854 
855  newCEP._normailzedPowerPatternPollutants
856  = CreatePattern(minNormPowerPattern,
857  maxNormPowerPattern,
859 
860  newCEP._cepCurvePollutants = new Dictionary<string, List<double>>();
861  newCEP._powerPatternPollutants = new List<double>();
862  newCEP._cepNormalizedCurvePollutants = new Dictionary<string, List<double>>();
863 
864  foreach (string id in cps.First()._cepCurvePollutants.Keys)
865  {
866  newCEP._cepCurvePollutants.Add(id, new List<double>());
867  newCEP._cepNormalizedCurvePollutants.Add(id, new List<double>());
868  }
869 
870  for (int i = 0; i < newCEP._normailzedPowerPatternPollutants.Count; i++)
871  {
872  foreach (string id in newCEP._cepCurvePollutants.Keys)
873  {
874  if (newCEP.NormalizingTypeX == NormalizingType.RatedPower)
875  {
876  double newCepVal = cps.Select(p => p.GetNormedEmission(id, newCEP._normailzedPowerPatternPollutants[i], double.MaxValue, Helper)).Sum();
877  newCEP._cepCurvePollutants[id].Add(newCepVal * newCEP._ratedPower);
878  newCEP._cepNormalizedCurvePollutants[id].Add(newCepVal);
879  }
880  else
881  {
882  newCEP._cepCurvePollutants[id].Add(cps.Select(p => p.GetEmission(id, newCEP._normailzedPowerPatternPollutants[i] * p._normalizingPower, double.MaxValue, Helper)).Sum());
883  newCEP._cepNormalizedCurvePollutants[id].Add(cps.Select(p => p.GetNormedEmission(id, newCEP._normailzedPowerPatternPollutants[i], double.MaxValue, Helper)).Sum());
884  }
885  }
886  newCEP._powerPatternPollutants.Add(newCEP._normailzedPowerPatternPollutants[i] * newCEP.NormalizingPower);
887  }
888  #endregion
889 
890  #region IdlingValues
891  newCEP._idlingValueFC = cps.Select(p => p._idlingValueFC).Sum();
892  newCEP._idlingValuesPollutants = new Dictionary<string, double>();
893 
894  foreach (string id in cps.First()._idlingValuesPollutants.Keys)
895  {
896  newCEP._idlingValuesPollutants.Add(id, cps.Select(p => p._idlingValuesPollutants[id]).Sum());
897  }
898  #endregion
899 
900  #region TragTable
901  double minTragTable = cps.Select(p => p._nNormTable.First()).Min();
902  double maxTragTable = cps.Select(p => p._nNormTable.Last()).Max();
903 
904  newCEP._nNormTable
905  = CreatePattern(minTragTable,
906  maxTragTable,
908 
909  newCEP._dragNormTable = new List<double>();
910 
911  for (int i = 0; i < newCEP._nNormTable.Count; i++)
912  {
913  newCEP._dragNormTable.Add(cps.Select(p => p.GetDragCoeffecient(newCEP._nNormTable[i])).Sum());
914  }
915  #endregion
916  return newCEP;
917  }
918  #endregion
919 
920  #region Operator *
921  public static CEP operator *(CEP cp1, double d)
922  {
923  #region SingleValues
924  CEP newCEP = new CEP(cp1.HeavyVehicle,
925  d * cp1._massVehicle,
926  d * cp1._vehicleLoading,
927  d * cp1._vehicleMassRot,
928  d * cp1._crossSectionalArea,
929  d * cp1._cWValue,
930  d * cp1._resistanceF0,
931  d * cp1._resistanceF1,
932  d * cp1._resistanceF2,
933  d * cp1._resistanceF3,
934  d * cp1._resistanceF4,
935  d * cp1._axleRatio,
936  d * cp1._auxPower,
937  d * cp1._ratedPower,
938  d * cp1._engineIdlingSpeed,
939  d * cp1._engineRatedSpeed,
940  d * cp1._effectiveWheelDiameter,
941  d * cp1._pNormV0,
942  d * cp1._pNormP0,
943  d * cp1._pNormV1,
944  d * cp1._pNormP1);
945 
946  newCEP._fuelType = cp1.FuelType;
947  #endregion
948 
949  #region SpeedRotationalTable
950  newCEP._speedPatternRotational = new List<double>(cp1._speedPatternRotational);
951  newCEP._speedCurveRotational = new List<double>(cp1._speedCurveRotational.Select(p => p * d));
952  newCEP._gearTransmissionCurve = new List<double>(cp1._gearTransmissionCurve.Select(p => p * d));
953  #endregion
954 
955  #region NormalizingPower
956  newCEP._drivingPower = newCEP.CalcPower(Constants.NORMALIZING_SPEED, Constants.NORMALIZING_ACCELARATION, 0);
957 
958  if (newCEP._heavyVehicle)
959  {
960  newCEP._normalizingPower = newCEP._ratedPower;
961  newCEP._normalizingType = NormalizingType.RatedPower;
962  }
963  else
964  {
965  newCEP._normalizingPower = newCEP._drivingPower;
966  newCEP._normalizingType = NormalizingType.DrivingPower;
967  }
968  #endregion
969 
970  #region FC
971  newCEP._powerPatternFC = new List<double>(cp1._powerPatternFC.Select(p => p * d));
972  newCEP._normalizedPowerPatternFC = new List<double>(cp1._normalizedPowerPatternFC);
973  newCEP._cepCurveFC = new List<double>(cp1._cepCurveFC.Select(p => p * d));
974  newCEP._normedCepCurveFC = new List<double>(cp1._normedCepCurveFC.Select(p => p * d));
975  #endregion
976 
977  #region Pollutants
978  newCEP._powerPatternPollutants = new List<double>(cp1._normailzedPowerPatternPollutants.Select(p => p * newCEP._normalizingPower));
979  newCEP._normailzedPowerPatternPollutants = new List<double>(cp1._normailzedPowerPatternPollutants);
980  newCEP._cepCurvePollutants = new Dictionary<string, List<double>>();
981  newCEP._cepNormalizedCurvePollutants = new Dictionary<string, List<double>>();
982 
983  foreach (string id in cp1._cepCurvePollutants.Keys)
984  {
985  newCEP._cepCurvePollutants.Add(id, new List<double>(cp1._cepCurvePollutants[id].Select(p => p * d)));
986  newCEP._cepNormalizedCurvePollutants.Add(id, new List<double>(cp1._cepNormalizedCurvePollutants[id].Select(p => p * d)));
987  }
988  #endregion
989 
990  #region IdlingValues
991  newCEP._idlingValueFC = cp1._idlingValueFC * d;
992  newCEP._idlingValuesPollutants = new Dictionary<string, double>();
993 
994  foreach (string id in cp1._idlingValuesPollutants.Keys)
995  {
996  newCEP._idlingValuesPollutants.Add(id,
997  cp1._idlingValuesPollutants[id] * d);
998  }
999  #endregion
1000 
1001  #region DragTable
1002  newCEP._nNormTable = new List<double>(cp1._nNormTable);
1003  newCEP._dragNormTable = new List<double>(cp1._dragNormTable.Select(p => p * d));
1004  #endregion
1005  return newCEP;
1006  }
1007  #endregion
1008 
1009  #region CreatePattern
1010  static public List<double> CreatePattern(double min, double max, double increment)
1011  {
1012  //Declaration
1013  List<double> pattern = new List<double>();
1014  double actualMin = min;
1015  double actualMax = max;
1016 
1017  if (min < 0)
1018  actualMin = Math.Ceiling(min / increment) * increment;
1019  else
1020  actualMin = Math.Floor(min / increment) * increment;
1021 
1022  if (max < 0)
1023  actualMax = Math.Floor(max / increment) * increment;
1024  else
1025  actualMax = Math.Ceiling(max / increment) * increment;
1026 
1027  double curVal = actualMin;
1028 
1029  while (curVal <= actualMax)
1030  {
1031  pattern.Add(curVal);
1032  curVal += increment;
1033  }
1034  return pattern;
1035  }
1036  #endregion
1037  #endif
1038  }
1039 }
NormalizingType
Definition: PHEMCEP.h:36
std::vector< double > _powerPatternPollutants
Definition: cpp/CEP.h:116
std::vector< double > _dragNormTable
Definition: cpp/CEP.h:128
double GetGearCoeffecient(double speed)
std::vector< double > _powerPatternFC
Definition: cpp/CEP.h:113
double _pNormP1
Definition: cpp/CEP.h:106
double GetPMaxNorm(double speed)
Definition: cpp/CEP.cpp:427
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: cpp/CEP.cpp:32
std::vector< double > _nNormTable
Definition: cpp/CEP.h:127
double _pNormP0
Definition: cpp/CEP.h:104
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: dll_code/CEP.cs:17
double GetEmission(string pollutant, double power, double speed, Helpers VehicleClass)
double _effectiveWheelDiameter
Definition: cpp/CEP.h:110
double GetDragCoeffecient(double nNorm)
double _drivingPower
Definition: cpp/CEP.h:83
double _axleRatio
Definition: cpp/CEP.h:101
std::map< std::string, std::vector< double > > _cepNormalizedCurvePollutants
Definition: cpp/CEP.h:123
std::map< std::string, double > _idlingValuesPollutants
Definition: cpp/CEP.h:125
double GetMaxAccel(double speed, double gradient)
double _vehicleLoading
Definition: cpp/CEP.h:92
static CEP AddRangeCeps(CEP[] cps, Helpers Helper)
bool _heavyVehicle
Definition: cpp/CEP.h:52
List< double > _dragNormTable
std::vector< double > _speedPatternRotational
Definition: cpp/CEP.h:112
Dictionary< string, List< double > > _cepNormalizedCurvePollutants
List< double > _cepCurveFC
List< double > _nNormTable
double _ratedPower
Definition: cpp/CEP.h:72
std::vector< double > _normalizedPowerPatternFC
Definition: cpp/CEP.h:114
double _normalizingPower
Definition: cpp/CEP.h:78
double GetNormedEmission(string pollutant, double power, double speed, Helpers VehicleClass)
NormalizingType _normalizingType
Definition: cpp/CEP.h:67
double _resistanceF2
Definition: cpp/CEP.h:98
double _resistanceF3
Definition: cpp/CEP.h:99
List< double > _normalizedPowerPatternFC
double _pNormV1
Definition: cpp/CEP.h:105
Dictionary< string, double > _idlingValuesPollutants
NormalizingType NormalizingTypeX
std::vector< double > _cepCurveFC
Definition: cpp/CEP.h:118
double _cWValue
Definition: cpp/CEP.h:95
static CEP operator*(CEP cp1, double d)
List< double > _powerPatternPollutants
std::vector< double > _normedCepCurveFC
Definition: cpp/CEP.h:119
std::vector< double > _normailzedPowerPatternPollutants
Definition: cpp/CEP.h:115
double _crossSectionalArea
Definition: cpp/CEP.h:94
double _auxPower
Definition: cpp/CEP.h:102
void FindLowerUpperInPattern(int &lowerIndex, int &upperIndex, std::vector< double > &pattern, double value)
Definition: cpp/CEP.cpp:370
std::vector< double > _gearTransmissionCurve
Definition: cpp/CEP.h:120
double GetCO2Emission(double _FC, double _CO, double _HC, Helpers VehicleClass)
List< double > _speedPatternRotational
List< double > _normailzedPowerPatternPollutants
double GetRotationalCoeffecient(double speed)
Definition: cpp/CEP.cpp:361
std::string _fuelType
Definition: cpp/CEP.h:57
double CalcEngPower(double power)
List< double > _normedCepCurveFC
std::vector< double > _speedCurveRotational
Definition: cpp/CEP.h:121
void FindLowerUpperInPattern(out int lowerIndex, out int upperIndex, List< double > pattern, double value)
double _resistanceF4
Definition: cpp/CEP.h:100
static List< double > CreatePattern(double min, double max, double increment)
double _resistanceF0
Definition: cpp/CEP.h:96
double CalcPower(double speed, double acc, double gradient)
Definition: cpp/CEP.cpp:200
Dictionary< string, List< double > > _cepCurvePollutants
List< double > _powerPatternFC
double _idlingValueFC
Definition: cpp/CEP.h:124
List< double > _speedCurveRotational
double _pNormV0
Definition: cpp/CEP.h:103
double Interpolate(double px, double p1, double p2, double e1, double e2)
Definition: cpp/CEP.cpp:412
double _engineIdlingSpeed
Definition: cpp/CEP.h:109
double _engineRatedSpeed
Definition: cpp/CEP.h:108
std::map< std::string, std::vector< double > > _cepCurvePollutants
Definition: cpp/CEP.h:122
double _massVehicle
Definition: cpp/CEP.h:91
List< double > _gearTransmissionCurve
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)
double GetDecelCoast(double speed, double acc, double gradient)
double _resistanceF1
Definition: cpp/CEP.h:97
double _vehicleMassRot
Definition: cpp/CEP.h:93
static const std::string strBEV
Definition: cpp/Constants.h:63
static const double AIR_DENSITY_CONST
Definition: cpp/Constants.h:35
static const double SPEED_DCEL_MIN
Definition: cpp/Constants.h:38
static const std::string strLPG
Definition: cpp/Constants.h:61
static const double ZERO_SPEED_ACCURACY
Definition: cpp/Constants.h:39
static const double GRAVITY_CONST
Definition: cpp/Constants.h:34
static const std::string strDiesel
Definition: cpp/Constants.h:59
const double SPEED_ROTATIONAL_INCREMENT
const double POWER_POLLUTANT_INCREMENT
static const double NORMALIZING_ACCELARATION
Definition: cpp/Constants.h:37
static double _DRIVE_TRAIN_EFFICIENCY
static const std::string strGasoline
Definition: cpp/Constants.h:58
static const std::string strCNG
Definition: cpp/Constants.h:60
static const double NORMALIZING_SPEED
Definition: cpp/Constants.h:36