View Issue Details

IDProjectCategoryView StatusLast Update
0003850OpenFOAMBugpublic2022-06-24 11:34
Reportermturcios777 Assigned Tohenry  
Status resolvedResolutionfixed 
PlatformLinuxOSUbuntuOS Version20.04 LTS
Product Versiondev 
Fixed in Versiondev 
Summary0003850: Lagrangian injection uses realtime, but TimeFunction1 integral expects userTimes and can't follow flowRate as written
DescriptionI am currently working on updating our lagrangian models using userTime with engine models to work in OF-dev and was having trouble matching the flowRate profile. The massTotal is correct, but the flow profile does not.

In searching through the InjectionModel.C and the various implementations, the problem seems to occur in the volumeToInject function. According to the code, SOI, duration and the time arguments used to integrate are all in seconds; for example in ConeNozzle:
Conversion of duration:

However, volumeToInject uses the integral function for TimeFunction1, which expects userTime and converts to time:

There appears to be inconsistency in where the conversion of values should occur

I have been using mass basis parcels so that the total target mass is always injected. With the integration inconsistency, the flowRate is essentially truncated at whatever the duration scaled to real time is
Steps To ReproduceI am working on a test case to upload without proprietary information, but the basic steps are:

1) Create a case with a cloud that has a userTime (engine cases with any kind of injector should suffice)
2) Specify the duration,flowRate and SOI in the appropriate userTime (Crank angle degrees in an engine case)
3) Make the parcelBasis mass so that the total mass at the end of injection is respected no matter what
3) Run the simulation and plot the liquid mass injected

Additional InformationConverting the flowRate to time does nothing as the initial scaling and truncation happen when volumeTotal is calculated.
TagsNo tags attached.



2022-06-22 06:54

reporter   ~0012630

Test case with logfiles of liquid injected mass, columns are:
Time numbeParcelsAdded massIntroduced liquidPenetration


2022-06-22 07:36

reporter   ~0012631

Updated case to have separate files for time and userTime injection flowRate profiles


2022-06-22 09:05

manager   ~0012632

> According to the code, SOI, duration and the time arguments used to integrate are all in seconds

Would you rather the injection specification were in CA or seconds? We discussed this when updating the implementation and concluded that seconds would probably be better for injectors.


2022-06-22 11:25

manager   ~0012633

The injection models convert the start of injection and duration from userTime to time:

    SOI_ = owner.db().time().userTimeToTime(SOI_);

    duration_ = owner.db().time().userTimeToTime(duration_);

Would you rather all injection specification were in real time or some in real time and some in user time?


2022-06-22 13:33

manager   ~0012634

If the profiles are specified in user-time I think TimeFunction1 should be changed thus:

template<class Type>
Type Foam::TimeFunction1<Type>::value(const scalar x) const
    return function_->value(time_.timeToUserTime(x));

template<class Type>
Type Foam::TimeFunction1<Type>::integral
    const scalar x1,
    const scalar x2
) const

I am not sure how to run your case or analyse or interpret the results, could you test this change and let me know if it resolves the issue.


2022-06-22 14:59

reporter   ~0012635

Thank you for looking into this. Prior to the change in how time is handled, if a simulation was an engine simulation then everything was specified in userTime. I think having all inputs to be in userTime would require the least modifications to the codebase. I will test the proposed code change and get back to you.

I also realize I didn't leave enough instructions, it was super late when I finished that case. The case uses reactingFoam. There is an include statement at the top of the system/controlDict in workDir, as well as in constant/liquidSprayProperties. To run the case as an engine case, change these includes to


To run as a regular case, change the include to


And temporarily remove the dynamicMeshDict


2022-06-22 15:04

manager   ~0012636

> I think having all inputs to be in userTime would require the least modifications to the codebase.

Changing these inputs from user-time to time is easy and if it makes more sense to the users I am happy to make the change. I am not sure what the most common specification for injection in engines is so I will need input from the users of this functionality.


2022-06-22 17:22

reporter   ~0012637

This is a tricky design choice indeed. Injection, and in particular, injection duration, is a specific event which may not be intuitively correlated with the engine CAD time because then change in RPM would implicitly change the injection event, which in my opinion, results in easy mistakes and would require subsequent injection setup changes. On the other hand, different RPM requires typically different injection profile anyway...

Typically, fuel injection mass/volume flow rate profiles are estimated based on specific numerical tools or by experiments. Such profiles are typically expressed in SI units and when considering duration, it is estimated/given based on knowledge on injector control signals, expressed in seconds. However, start of injection (SOI) in user input dictionary is easiest to keep in CAD grasp on when the injection takes place.

Hence, for me the most logical input types would be:
- SOI: engineTime [CAD]
- profiles: SI units [m3/s or kg/s]
- duration: [seconds]

Of course, the above has a drawback of mixing units which is not a good habit either.

In the end, I believe that users create injection setups / profiles with some sort of script outside openfoam so I think clarity should be weighted most here.

Any ideas / comments mturcios777 ?


2022-06-22 17:43

reporter   ~0012638

@henry, the proposed fix does solve the problem and the flowRateProfile when specified in userTime is respected. We did have a concern that other libraries and objects that use TimeFunction1 may not function properly though if they assume that input is in userTime.

An alternative solution so that the flowProfile is in time which we have tested is to change any calls to value and integrate in ALL the injection models to use converted userTime. Searching through the code the injection models are the only place TimeFunction1 is used.

A third alternative is to use Function1 insteam of timeFunction1 and assume the user always has their profile correct. We have not tested this.

@peksa, in previous versions of OpenFOAM with the specific engineTime class, all the user inputs had to be CAD. This made sense to us as we have pre-processing scripts where RPM is an input parameter and the flowProfile is created in crank angle. I think most users would have a similar means of converting profiles.


2022-06-22 18:16

reporter   ~0012639

Here is input from a colleague who helped find the issue and propose the second possible workaround, for additional information:

Just to insist, the current implementation of the InjectorModels is inconsistent/bugged with the current design choice to convert all time-related variables in realTime (not userTime) and give the flowRateProfile in realTime (not userTime).

Indeed, the value() and integral() functions of the TimeFunction1 class (used to evaluate and integrate the flowRateProfile in InjectionModels), in their current implementation, take inputs in userTime (not realTime) and convert them to realTime using the function userTimeToTime(), as the flowRateProfile is given in realTime by design.

However, the variables fed to the functions value() and integral() in the InjectionModels are in realTime (design choice), whereas to use these functions the variables should be in fact in userTime. This results in an erroneous behavior of the InjectorModel in all instances where userTime is not realTime.

A proposed fix for the current design choice of converting all time variables to realTime and to keep the flowRateProfile in realTime is to convert to userTime the inputs of the functions value() and integral() using owner.db().time().timeToUserTime(x) in all calls to flowRateProfile.value() and flowRateProfile.integral() in the InjectorModels (not in TimeFunction1).

An alternative solution would be the proposed above fix, where all time variables are converted to realTime but the flowRateProfile is given in userTime, and where the evalute() and integral() functions of TimeFunction1 read in realTime variables and convert them to userTime (as the flowRateProfile is in userTime by design in this scenario).

Another solution is to keep all time variables in userTime as well as the flowRateProfile in the InjectionModels and to use the time variables as is in the functions value() and integrate() of TimeFunction1.


2022-06-22 18:46

manager   ~0012640

Last edited: 2022-06-22 18:59

I am capable if implementing any of the options, I just need to know which of the user inputs should be in CA and which is seconds.


2022-06-22 22:13

reporter   ~0012641

I will consult internally and get back to you by the end of the week.

On a design/architechture side, is there a reason we have the addition of TimeFunction1 and Function1. Is it to reduce the amount of conversions required for userTimes?

In any case, some documentation in the injectors and TimeFunction1 laying out which times are expected as arguments would be helpful, so we know when to supply them. Knowing that TimeFunction1 expects realTimes and integrates based on the equivalent userTime would have saved a lot of trouble in figuring out this bug.


2022-06-22 22:36

manager   ~0012642

TimeFunction1 is more convenient to use if the input table or function is specified in user time, that is the point. If the input were to be specified in real time then Function1 would be used and TimeFunction1 could be deleted.


2022-06-23 12:59

reporter   ~0012643

If we run our engine cases with injection, we normally specify the x-values, i.e. time, in CAD, i.e. userTime, and the y-values in SI units (kg/s)


2022-06-23 13:06

manager   ~0012644

Is that your preference or what you do because that is what is currently supported in OpenFOAM?


2022-06-23 14:13

reporter   ~0012645

This would be our preference. However, we currently do not have an injection setup in OpenFOAM (yet).


2022-06-23 22:18

reporter   ~0012646

Our preference would also be that the flowRate be specified in userTime.


2022-06-24 11:34

manager   ~0012650

Resolved by commit 9d50ffdfbb99a87bcf08bae7cfd5922ef07ad604

Issue History

Date Modified Username Field Change
2022-06-22 05:48 mturcios777 New Issue
2022-06-22 06:54 mturcios777 File Added: aachenEngineInjTest.tar.gz
2022-06-22 06:54 mturcios777 Note Added: 0012630
2022-06-22 07:36 mturcios777 File Added: aachenEngineInjTest.tar-2.gz
2022-06-22 07:36 mturcios777 Note Added: 0012631
2022-06-22 09:05 henry Note Added: 0012632
2022-06-22 11:25 henry Note Added: 0012633
2022-06-22 13:33 henry Note Added: 0012634
2022-06-22 14:59 mturcios777 Note Added: 0012635
2022-06-22 15:04 henry Note Added: 0012636
2022-06-22 17:22 peksa Note Added: 0012637
2022-06-22 17:43 mturcios777 Note Added: 0012638
2022-06-22 18:16 mturcios777 Note Added: 0012639
2022-06-22 18:46 henry Note Added: 0012640
2022-06-22 18:59 henry Note Edited: 0012640
2022-06-22 22:13 mturcios777 Note Added: 0012641
2022-06-22 22:36 henry Note Added: 0012642
2022-06-23 12:59 cgoessni Note Added: 0012643
2022-06-23 13:06 henry Note Added: 0012644
2022-06-23 14:13 cgoessni Note Added: 0012645
2022-06-23 22:18 mturcios777 Note Added: 0012646
2022-06-24 11:34 henry Assigned To => henry
2022-06-24 11:34 henry Status new => resolved
2022-06-24 11:34 henry Resolution open => fixed
2022-06-24 11:34 henry Fixed in Version => dev
2022-06-24 11:34 henry Note Added: 0012650