rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions
fuel_math.h File Reference

Detailed Description

Date
May 27, 2013
Author
Andrey Belomutskiy, (c) 2012-2020

Definition in file fuel_math.h.

Functions

void initFuelMap ()
 Initialize fuel map data structure.
 
float getRunningFuel (float baseFuel)
 
float getBaroCorrection ()
 
percent_t getFuelALSCorrection (float rpm)
 
int getNumberOfInjections (injection_mode_e mode)
 
angle_t getInjectionOffset (float rpm, float load)
 
float getIatFuelCorrection ()
 
float getPostCrankingFuelCorrection ()
 
float getCltFuelCorrection ()
 Engine warm-up fuel correction.
 
angle_t getCltTimingCorrection ()
 
float getCrankingFuel (float baseFuel)
 
float getCrankingFuel3 (float baseFuel, uint32_t revolutionCounterSinceStart)
 
float getInjectionMass (float rpm)
 
percent_t getInjectorDutyCycle (float rpm)
 
percent_t getInjectorDutyCycleStage2 (float rpm)
 
float getStage2InjectionFraction (float rpm, float fuelLoad)
 
float getStandardAirCharge ()
 
float getCylinderFuelTrim (size_t cylinderNumber, float rpm, float fuelLoad)
 
AirmassModelBasegetAirmassModel (engine_load_mode_e mode)
 
float getMaxAirflowAtMap (float map)
 
float getCycleFuelMass (bool isCranking, float baseFuelMass)
 

Function Documentation

◆ getAirmassModel()

AirmassModelBase * getAirmassModel ( engine_load_mode_e  mode)

Definition at line 156 of file fuel_math.cpp.

156 {
157#if EFI_UNIT_TEST
158 if (mode == engine_load_mode_e::UNSUPPORTED_ENUM_VALUE) {
159 return engine->mockAirmassModel;
160 }
161#endif
162
163 switch (mode) {
164 case engine_load_mode_e::LM_SPEED_DENSITY: return &sdAirmass;
165 case engine_load_mode_e::LM_REAL_MAF: return &mafAirmass;
166 case engine_load_mode_e::LM_ALPHA_N: return &alphaNAirmass;
167#if EFI_LUA
168 case engine_load_mode_e::LM_LUA: return &(getLuaAirmassModel());
169#endif
170 default:
172 return nullptr;
173 }
174}
AirmassModelBase * mockAirmassModel
Definition engine.h:382
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
void firmwareError(ObdCode code, const char *fmt,...)
static SpeedDensityAirmass sdAirmass(veMap, mapEstimationTable)
static MafAirmass mafAirmass(veMap)
static AlphaNAirmass alphaNAirmass(veMap)
AirmassModelBase & getLuaAirmassModel()
@ CUSTOM_ERR_ASSERT

Referenced by getBaseFuelMass(), and lua_getAirmass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getBaroCorrection()

float getBaroCorrection ( )

Definition at line 429 of file fuel_math.cpp.

429 {
431 // Default to 1atm if failed
432 float pressure = Sensor::get(SensorType::BarometricPressure).value_or(STD_ATMOSPHERE);
433
434 float correction = interpolate3d(
436 config->baroCorrPressureBins, pressure,
438 );
439
440 if (std::isnan(correction) || correction < 0.01) {
441 warning(ObdCode::OBD_Barometric_Press_Circ_Range_Perf, "Invalid baro correction %f", correction);
442 return 1;
443 }
444
445 return correction;
446 } else {
447 return 1;
448 }
449}
virtual bool hasSensor() const
Definition sensor.h:141
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
static constexpr persistent_config_s * config
bool warning(ObdCode code, const char *fmt,...)
@ OBD_Barometric_Press_Circ_Range_Perf
@ BarometricPressure

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCltFuelCorrection()

float getCltFuelCorrection ( )

Engine warm-up fuel correction.

Definition at line 386 of file fuel_math.cpp.

386 {
387 const auto clt = Sensor::get(SensorType::Clt);
388
389 if (!clt)
390 return 1; // this error should be already reported somewhere else, let's just handle it
391
392 return interpolate2d(clt.Value, config->cltFuelCorrBins, config->cltFuelCorr);
393}
static CCM_OPTIONAL FunctionalSensor clt(SensorType::Clt, MS2NT(10))

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCltTimingCorrection()

angle_t getCltTimingCorrection ( )

Referenced by IgnitionState::updateAdvanceCorrections().

Here is the caller graph for this function:

◆ getCrankingFuel()

float getCrankingFuel ( float  baseFuel)
Returns
Duration of fuel injection while craning

Definition at line 472 of file fuel_math.cpp.

472 {
474}
RpmCalculator rpmCalculator
Definition engine.h:306
uint32_t getRevolutionCounterSinceStart(void) const
float getCrankingFuel3(float baseFuel, uint32_t revolutionCounterSinceStart)
Definition fuel_math.cpp:42

Referenced by getCycleFuelMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCrankingFuel3()

float getCrankingFuel3 ( float  baseFuel,
uint32_t  revolutionCounterSinceStart 
)

Cranking fuel is different depending on engine coolant temperature If the sensor is failed, use 20 deg C

Definition at line 42 of file fuel_math.cpp.

42 {
43
44 float baseCrankingFuel;
46 baseCrankingFuel = baseFuel;
47 } else {
48 // Cranking fuel changes over time
49 baseCrankingFuel = interpolate3d(
53 ) * 0.001f; // parameter is in milligrams, convert to grams
54 }
55
56 engine->engineState.crankingFuel.baseFuel = baseCrankingFuel * 1000; // convert to mg
57
58 /**
59 * Cranking fuel is different depending on engine coolant temperature
60 * If the sensor is failed, use 20 deg C
61 */
62 auto clt = Sensor::get(SensorType::Clt).value_or(20);
63 auto e0Mult = interpolate2d(clt, config->crankingFuelBins, config->crankingFuelCoef);
64
65 bool alreadyWarned = false;
66 if (e0Mult <= 0.1f) {
67 warning(ObdCode::CUSTOM_ERR_ZERO_E0_MULT, "zero e0 multiplier");
68 alreadyWarned = true;
69 }
70
72 auto e85Mult = interpolate2d(clt, config->crankingFuelBins, config->crankingFuelCoefE100);
73
74 if (e85Mult <= 0.1f) {
75 warning(ObdCode::CUSTOM_ERR_ZERO_E85_MULT, "zero e85 multiplier");
76 alreadyWarned = true;
77 }
78
79 // If failed flex sensor, default to 50% E
80 auto flex = Sensor::get(SensorType::FuelEthanolPercent).value_or(50);
81
84 0, e0Mult,
85 85, e85Mult,
86 flex
87 );
88 } else {
90 }
91
94 tps.Valid
95 ? interpolate2d(tps.Value, config->crankingTpsBins, config->crankingTpsCoef)
96 : 1; // in case of failed TPS, don't correct.
97
98 floatms_t crankingFuel = baseCrankingFuel
101
103
104 // don't re-warn for zero fuel when we already warned for a more specific problem
105 if (!alreadyWarned && crankingFuel <= 0) {
107 }
108 return crankingFuel;
109}
EngineState engineState
Definition engine.h:344
float interpolateClamped(float x1, float y1, float x2, float y2, float x)
@ CUSTOM_ERR_ZERO_E85_MULT
@ CUSTOM_ERR_ZERO_CRANKING_FUEL
@ CUSTOM_ERR_ZERO_E0_MULT
float floatms_t
@ FuelEthanolPercent
@ DriverThrottleIntent
revolutionCounterSinceStart("revolutionCounterSinceStart", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 64, 1.0, 0.0, 0.0, "")
crankingFuel("crankingFuel", SensorCategory.SENSOR_INPUTS, FieldType.INT, 1352, 1.0, -1.0, -1.0, "")
scaled_channel< uint16_t, 100, 1 > baseFuel
scaled_channel< uint16_t, 100, 1 > fuel
cranking_fuel_s crankingFuel
float crankingCycleBaseFuel[CRANKING_CYCLE_CLT_SIZE][CRANKING_CURVE_SIZE]
scaled_channel< uint16_t, 100, 1 > crankingFuelCoefE100[CRANKING_CURVE_SIZE]

Referenced by getCrankingFuel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCycleFuelMass()

float getCycleFuelMass ( bool  isCranking,
float  baseFuelMass 
)

Definition at line 300 of file fuel_math.cpp.

300 {
301 if (isCranking) {
302 return getCrankingFuel(baseFuelMass);
303 } else {
304 return getRunningFuel(baseFuelMass);
305 }
306}
float getRunningFuel(float baseFuel)
float getCrankingFuel(float baseFuel)

Referenced by getInjectionMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCylinderFuelTrim()

float getCylinderFuelTrim ( size_t  cylinderNumber,
float  rpm,
float  fuelLoad 
)

Definition at line 491 of file fuel_math.cpp.

491 {
492 auto trimPercent = interpolate3d(
493 config->fuelTrims[cylinderNumber].table,
494 config->fuelTrimLoadBins, fuelLoad,
496 );
497
498 // Convert from percent +- to multiplier
499 // 5% -> 1.05
500 // possible optimization: remove division by moving this scaling to TS level
501 return (100 + trimPercent) / 100;
502}
scaled_channel< int8_t, 5, 1 > table[FUEL_TRIM_SIZE][FUEL_TRIM_SIZE]

Referenced by EngineState::periodicFastCallback().

Here is the caller graph for this function:

◆ getFuelALSCorrection()

percent_t getFuelALSCorrection ( float  rpm)

Definition at line 451 of file fuel_math.cpp.

451 {
452#if EFI_ANTILAG_SYSTEM
455 auto AlsFuelAdd = interpolate3d(
457 config->alsFuelAdjustmentLoadBins, throttleIntent,
459 );
460 return AlsFuelAdd;
461 } else
462#endif /* EFI_ANTILAG_SYSTEM */
463 {
464 return 0;
465 }
466}
AntilagSystemBase antilagController
Definition engine.h:228
scaled_channel< int16_t, 10, 1 > ALSFuelAdjustment[ALS_SIZE][ALS_SIZE]

Referenced by AntilagSystemBase::update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getIatFuelCorrection()

float getIatFuelCorrection ( )

Definition at line 395 of file fuel_math.cpp.

395 {
396 const auto iat = Sensor::get(SensorType::Iat);
397
398 if (!iat)
399 return 1; // this error should be already reported somewhere else, let's just handle it
400
401 return interpolate2d(iat.Value, config->iatFuelCorrBins, config->iatFuelCorr);
402}
static CCM_OPTIONAL FunctionalSensor iat(SensorType::Iat, MS2NT(10))

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectionMass()

float getInjectionMass ( float  rpm)
Returns
Mass of each individual fuel injection, in grams in case of single point injection mode the amount of fuel into all cylinders, otherwise the amount for one cylinder

Definition at line 312 of file fuel_math.cpp.

312 {
314
315 // Always update base fuel - some cranking modes use it
316 float baseFuelMass = getBaseFuelMass(rpm);
317
318 bool isCranking = engine->rpmCalculator.isCranking();
319 float cycleFuelMass = getCycleFuelMass(isCranking, baseFuelMass);
320 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(cycleFuelMass), "NaN cycleFuelMass", 0);
321
322 if (engine->module<DfcoController>()->cutFuel()) {
323 // If decel fuel cut, zero out fuel
324 cycleFuelMass = 0;
325 }
326
327 float durationMultiplier = getInjectionModeDurationMultiplier();
328 float injectionFuelMass = cycleFuelMass * durationMultiplier;
329
330 // Prepare injector flow rate & deadtime
331 engine->module<InjectorModelPrimary>()->prepare();
332
334 engine->module<InjectorModelSecondary>()->prepare();
335 }
336
337 // This variable will hold the extra fuel mass from legacy AE modes
338 float tpsFuelMass = 0;
339
340 // Get the AE value (it will be 0 if predictive mode is active)
341 float tpsAccelEnrich = engine->module<TpsAccelEnrichment>()->getTpsEnrichment();
342 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(tpsAccelEnrich), "NaN tpsAccelEnrich", 0);
343 engine->engineState.tpsAccelEnrich = tpsAccelEnrich;
344
345 float tpsAccelPerInjection = durationMultiplier * tpsAccelEnrich;
346
347 // Use a switch to handle all AE modes
349 case AE_MODE_PERCENT_ADDER:
350 // Treat the tpsAccelEnrich value as a percentage
351 tpsFuelMass = injectionFuelMass * tpsAccelPerInjection;
352 break;
353
354 case AE_MODE_MS_ADDER:
355 // For legacy reasons, the TPS accel table is in units of milliseconds,
356 // so we have to convert BACK to mass
357 tpsFuelMass = engine->module<InjectorModelPrimary>()->getFuelMassForDuration(tpsAccelPerInjection);
358 break;
359
360 case AE_MODE_PREDICTIVE_MAP:
361 // Do nothing here. Fuel correction has already been handled by providing a
362 // corrected MAP value to the getBaseFuelMass() calculation.
363 break;
364
365 default:
366 criticalError("Invalid accelEnrichmentMode %d", engineConfiguration->accelEnrichmentMode);
367 break;
368 }
369
370 return injectionFuelMass + tpsFuelMass;
371}
bool cutFuel() const
Definition dfco.cpp:81
constexpr auto & module()
Definition engine.h:200
floatms_t tpsAccelEnrich
bool isCranking() const override
static float getBaseFuelMass(float rpm)
float getCycleFuelMass(bool isCranking, float baseFuelMass)
float getInjectionModeDurationMultiplier()
@ GetInjectionDuration
accel_enrichment_mode_e

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectionOffset()

angle_t getInjectionOffset ( float  rpm,
float  load 
)

Definition at line 217 of file fuel_math.cpp.

217 {
218 if (std::isnan(rpm)) {
219 return 0; // error already reported
220 }
221
222 if (std::isnan(load)) {
223 return 0; // error already reported
224 }
225
226 angle_t value = interpolate3d(
230 );
231
232 if (std::isnan(value)) {
233 // we could be here while resetting configuration for example
234 // huh? what? when do we have RPM while resetting configuration? is that CI edge case? shall we fix CI?
235 warning(ObdCode::CUSTOM_ERR_6569, "phase map not ready");
236 return 0;
237 }
238
239 angle_t result = value;
240 wrapAngle(result, "inj offset#2", ObdCode::CUSTOM_ERR_6553);
241 return result;
242}
@ CUSTOM_ERR_6553
@ CUSTOM_ERR_6569
float angle_t
int16_t injectionPhase[INJ_PHASE_LOAD_COUNT][INJ_PHASE_RPM_COUNT]
void wrapAngle(angle_t &angle, const char *msg, ObdCode code)

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectorDutyCycle()

percent_t getInjectorDutyCycle ( float  rpm)

Definition at line 288 of file fuel_math.cpp.

288 {
290 floatms_t engineCycleDuration = getEngineCycleDuration(rpm);
291 return 100 * totalInjectiorAmountPerCycle / engineCycleDuration;
292}
floatms_t injectionDuration
floatms_t getEngineCycleDuration(float rpm)
int getNumberOfInjections(injection_mode_e mode)

Referenced by canDashboardHaltech(), EngineState::periodicFastCallback(), populateFrame(), LimpManager::updateState(), and updateTunerStudioState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectorDutyCycleStage2()

percent_t getInjectorDutyCycleStage2 ( float  rpm)

Definition at line 294 of file fuel_math.cpp.

294 {
296 floatms_t engineCycleDuration = getEngineCycleDuration(rpm);
297 return 100 * totalInjectiorAmountPerCycle / engineCycleDuration;
298}
floatms_t injectionDurationStage2

Referenced by updateTunerStudioState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getMaxAirflowAtMap()

float getMaxAirflowAtMap ( float  map)

Definition at line 176 of file fuel_math.cpp.

176 {
178}
float getAirflow(float rpm, float map, bool postState)

Referenced by ThrottleModel::maxEngineFlow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getNumberOfInjections()

int getNumberOfInjections ( injection_mode_e  mode)

Number of injections using each injector per engine cycle

See also
getNumberOfSparks

Definition at line 248 of file fuel_math.cpp.

248 {
249 switch (mode) {
250 case IM_SIMULTANEOUS:
251 case IM_SINGLE_POINT:
253 case IM_BATCH:
254 return 2;
255 case IM_SEQUENTIAL:
256 return 1;
257 default:
258 firmwareError(ObdCode::CUSTOM_ERR_INVALID_INJECTION_MODE, "Unexpected injection_mode_e %d", mode);
259 return 1;
260 }
261}
@ CUSTOM_ERR_INVALID_INJECTION_MODE

Referenced by getInjectorDutyCycle(), getInjectorDutyCycleStage2(), and InjectionEvent::onTriggerTooth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getPostCrankingFuelCorrection()

float getPostCrankingFuelCorrection ( )

Definition at line 404 of file fuel_math.cpp.

404 {
405 const auto revolutionCounter = engine->rpmCalculator.getRevolutionCounterSinceStart();
406 // if the engine run time is past the last bin, disable ASE in case the table is filled with values more than 1.0, helps with compatibility
407 if (revolutionCounter > config->postCrankingDurationBins[efi::size(config->postCrankingDurationBins) - 1])
408 return 1;
409
410 // TODO:
411 //const auto clt = Sensor::get(SensorType::Clt);
412 //if (!clt)
413 // return 1; // this error should be already reported somewhere else, let's just handle it
414
415 // post-cranking fuel enrichment.
416 float postCrankingFactor = interpolate3d(
419 config->postCrankingDurationBins, revolutionCounter
420 );
421
422 // for compatibility reasons, apply only if the factor is greater than unity (only allow adding fuel)
423 if (postCrankingFactor < 1.0f)
424 postCrankingFactor = 1.0f;
425
426 return postCrankingFactor;
427}
float postCrankingFactor[CRANKING_ENRICH_CLT_COUNT][CRANKING_ENRICH_COUNT]

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getRunningFuel()

float getRunningFuel ( float  baseFuel)
Returns
baseFuel with CLT and IAT corrections

Definition at line 111 of file fuel_math.cpp.

111 {
113
116 float postCrankingFuelCorrection = engine->fuelComputer.running.postCrankingFuelCorrection;
118
119 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(iatCorrection), "NaN iatCorrection", 0);
120 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(cltCorrection), "NaN cltCorrection", 0);
121 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(postCrankingFuelCorrection), "NaN postCrankingFuelCorrection", 0);
122
123 float correction = baroCorrection * iatCorrection * cltCorrection * postCrankingFuelCorrection;
124
125#if EFI_ANTILAG_SYSTEM
126 correction *= (1 + engine->antilagController.fuelALSCorrection / 100);
127#endif /* EFI_ANTILAG_SYSTEM */
128
129#if EFI_LAUNCH_CONTROL
131 correction *= engine->module<NitrousController>().unmock().getFuelCoefficient();
132#endif
133
134#ifdef MODULE_VVL_CONTROLLER
135 correction *= engine->module<VvlController>().unmock().getFuelCoefficient();
136#endif /* MODULE_VVL_CONTROLLER */
137
138 correction *= getLimpManager()->getLimitingFuelCorrection();
139
140 float runningFuel = baseFuel * correction;
141
142 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(runningFuel), "NaN runningFuel", 0);
143
144 // Publish output state
145 engine->fuelComputer.running.baseFuel = baseFuel * 1000;
147 engine->fuelComputer.running.fuel = runningFuel * 1000;
148
149 return runningFuel;
150}
FuelComputer fuelComputer
Definition engine.h:139
LaunchControlBase launchController
Definition engine.h:220
float getFuelCoefficient() const
float getLimitingFuelCorrection() const
float getFuelCoefficient() const
float getFuelCoefficient() const
LimpManager * getLimpManager()
Definition engine.cpp:596
@ GetRunningFuel
baroCorrection("Fuel: Barometric pressure mult", SensorCategory.SENSOR_INPUTS, FieldType.INT, 1364, 1.0, -1.0, -1.0, "")
scaled_channel< uint16_t, 100, 1 > baseFuel
scaled_channel< uint16_t, 100, 1 > fuel

Referenced by getCycleFuelMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getStage2InjectionFraction()

float getStage2InjectionFraction ( float  rpm,
float  fuelLoad 
)

Definition at line 506 of file fuel_math.cpp.

506 {
508 return 0;
509 }
510
511 float frac = 0.01f * interpolate3d(
515 );
516
517 // don't allow very small fraction, with some hysteresis
518 if (!stage2Hysteresis.test(frac, 0.1, 0.03)) {
519 return 0;
520 }
521
522 // Clamp to 90%
523 if (frac > 0.9) {
524 frac = 0.9;
525 }
526
527 return frac;
528}
bool test(float value, float rising, float falling)
Definition hysteresis.h:31
static Hysteresis stage2Hysteresis
uint8_t injectorStagingTable[INJ_STAGING_COUNT][INJ_STAGING_COUNT]

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getStandardAirCharge()

float getStandardAirCharge ( )

Standard cylinder air charge - 100% VE at standard temperature, grams per cylinder

Should we bother caching 'getStandardAirCharge' result or can we afford to run the math every time we calculate fuel?

Definition at line 481 of file fuel_math.cpp.

481 {
482 float totalDisplacement = engineConfiguration->displacement;
483 float cylDisplacement = totalDisplacement / engineConfiguration->cylindersCount;
484
485 // Calculation of 100% VE air mass in g/cyl - 1 cylinder filling at 1.204/L
486 // 101.325kpa, 20C
487 return idealGasLaw(cylDisplacement, STD_ATMOSPHERE, C_K_OFFSET + STD_IAT);
488}
mass_t idealGasLaw(float volume, float pressure, float temperature)

Referenced by MafAirmass::getAirmassImpl(), and getBaseFuelMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initFuelMap()

void initFuelMap ( )

Initialize fuel map data structure.

Note
this method has nothing to do with fuel map VALUES - it's job is to prepare the fuel map data structure for 3d interpolation

Definition at line 379 of file fuel_math.cpp.

379 {
381}
void initTable(TValueInit(&table)[TRowNum][TColNum], const TXColumnInit(&columnBins)[TColNum], const TRowInit(&rowBins)[TRowNum])
static mapEstimate_Map3D_t mapEstimationTable
Definition fuel_math.cpp:38
scaled_channel< uint16_t, 100, 1 > mapEstimateTpsBins[MAP_EST_LOAD_COUNT]
scaled_channel< uint16_t, 100, 1 > mapEstimateTable[MAP_EST_LOAD_COUNT][MAP_EST_RPM_COUNT]

Referenced by initDataStructures().

Here is the call graph for this function:
Here is the caller graph for this function:

Go to the source code of this file.