View Issue Details

IDProjectCategoryView StatusLast Update
0000953OpenFOAMBugpublic2016-02-03 13:21
Reporterdkxls Assigned Tohenry  
PriorityhighSeverityminorReproducibilityalways
Status closedResolutionno change required 
PlatformLinux x86_64OSopenSUSEOS Version12.2
Summary0000953: [Lagrangian]: Missing Lagrangian sub-cycle (i.e. the Lagrangian time-step) setting
DescriptionIn the current implementation the Lagrangian sub-cycles (i.e. the Lagrangian time-step) cannot be set by the user. The number of sub-cycles is always 1 (i.e. carrierDt = lagrangianDt), except during injection.

I believe, this feature requires only minor changes, as all necessary infrastructure is implemented already! The changes would only concern the following step:
1. reading the number of sub-cycles from the dictionary (probably best in cloudSolution)
2. set 'dtMax = tEnd/nSubCycle' (in the function Foam::KinematicParcel<ParcelType>::move)

Lagrangian sub-cycles are important/necessary to achieve a stable solution in many spray simulation and this has been a feature of the dieselSpray implementation.
Additional Informationlagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C

https://github.com/OpenFOAM/OpenFOAM-2.0.x/blob/master/src/lagrangian/dieselSpray/parcel/parcel.C
Tagscontribution, Lagrangian, spray, sprayEngineFoam, sprayFoam

Activities

dkxls

2013-08-13 19:50

reporter  

0001-Add-subcycles-to-Lagrangian.patch (4,581 bytes)   
From 1814a83f01ac833f0a28e537579e6674f8cd3df3 Mon Sep 17 00:00:00 2001
From: Armin Wehrfritz <armin.wehrfritz@aalto.fi>
Date: Tue, 13 Aug 2013 21:28:36 +0300
Subject: [PATCH] Add subcycles to Lagrangian

---
 .../Templates/KinematicCloud/cloudSolution/cloudSolution.C    |    9 +++++++++
 .../Templates/KinematicCloud/cloudSolution/cloudSolution.H    |    7 +++++++
 .../Templates/KinematicCloud/cloudSolution/cloudSolutionI.H   |    6 ++++++
 .../parcels/Templates/KinematicParcel/KinematicParcel.C       |    2 +-
 4 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
index fd7bf31..70da8f4 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
@@ -38,6 +38,7 @@ Foam::cloudSolution::cloudSolution
     dict_(dict),
     active_(dict.lookup("active")),
     transient_(false),
+    subCycles_(1),
     calcFrequency_(1),
     maxCo_(0.3),
     iter_(1),
@@ -64,6 +65,7 @@ Foam::cloudSolution::cloudSolution
     dict_(cs.dict_),
     active_(cs.active_),
     transient_(cs.transient_),
+    subCycles_(cs.subCycles_),
     calcFrequency_(cs.calcFrequency_),
     maxCo_(cs.maxCo_),
     iter_(cs.iter_),
@@ -85,6 +87,7 @@ Foam::cloudSolution::cloudSolution
     dict_(dictionary::null),
     active_(false),
     transient_(false),
+    subCycles_(1),
     calcFrequency_(0),
     maxCo_(GREAT),
     iter_(0),
@@ -123,6 +126,12 @@ void Foam::cloudSolution::read()
                 >> resetSourcesOnStartup_;
         }
     }
+    else
+    {
+        dict_.lookup("subCycles") >> subCycles_;
+        subCycles_ = max(subCycles_,1);
+//         dict_.lookupOrDefault<int>("subCycles",1) >> subCycles_;
+    }
 
     if (coupled_)
     {
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H
index e155abc..eac387b 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H
@@ -65,6 +65,10 @@ class cloudSolution
         //- Transient flag
         Switch transient_;
 
+        //- Sub cycles - cloud steps per carrier step
+        //  NOTE: Transient operation only
+        label subCycles_;
+
         //- Calculation frequency - carrier steps per cloud step
         //  NOTE: Steady operation only
         label calcFrequency_;
@@ -156,6 +160,9 @@ public:
             //- Return const access to the steady flag
             inline const Switch steadyState() const;
 
+            //- Return const access to the sub cycles
+            inline const label subCycles() const;
+
             //- Return const access to the calculation frequency
             inline label calcFrequency() const;
 
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H
index 6280b97..64672e2 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H
@@ -71,6 +71,12 @@ inline const Foam::Switch Foam::cloudSolution::steadyState() const
 }
 
 
+inline const Foam::label Foam::cloudSolution::subCycles() const
+{
+    return subCycles_;
+}
+
+
 inline Foam::label Foam::cloudSolution::calcFrequency() const
 {
     return calcFrequency_;
diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
index 7ec52b1..cbd3417 100644
--- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
+++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
@@ -275,7 +275,7 @@ bool Foam::KinematicParcel<ParcelType>::move
     const scalar maxCo = td.cloud().solution().maxCo();
 
     scalar tEnd = (1.0 - p.stepFraction())*trackTime;
-    const scalar dtMax = tEnd;
+    const scalar dtMax = tEnd/td.cloud().solution().subCycles();
 
     while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
     {
-- 
1.7.10.4

dkxls

2013-08-14 11:50

reporter  

0001-Add-subcycles-to-Lagrangian_v1.patch (3,988 bytes)   
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
index fd7bf31..70da8f4 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
@@ -38,6 +38,7 @@ Foam::cloudSolution::cloudSolution
     dict_(dict),
     active_(dict.lookup("active")),
     transient_(false),
+    subCycles_(1),
     calcFrequency_(1),
     maxCo_(0.3),
     iter_(1),
@@ -64,6 +65,7 @@ Foam::cloudSolution::cloudSolution
     dict_(cs.dict_),
     active_(cs.active_),
     transient_(cs.transient_),
+    subCycles_(cs.subCycles_),
     calcFrequency_(cs.calcFrequency_),
     maxCo_(cs.maxCo_),
     iter_(cs.iter_),
@@ -85,6 +87,7 @@ Foam::cloudSolution::cloudSolution
     dict_(dictionary::null),
     active_(false),
     transient_(false),
+    subCycles_(1),
     calcFrequency_(0),
     maxCo_(GREAT),
     iter_(0),
@@ -123,6 +126,12 @@ void Foam::cloudSolution::read()
                 >> resetSourcesOnStartup_;
         }
     }
+    else
+    {
+        dict_.lookup("subCycles") >> subCycles_;
+        subCycles_ = max(subCycles_,1);
+//         dict_.lookupOrDefault<int>("subCycles",1) >> subCycles_;
+    }
 
     if (coupled_)
     {
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H
index e155abc..92596a8 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.H
@@ -65,6 +65,10 @@ class cloudSolution
         //- Transient flag
         Switch transient_;
 
+        //- Sub cycles - cloud steps per carrier step
+        //  NOTE: Transient operation only
+        label subCycles_;
+
         //- Calculation frequency - carrier steps per cloud step
         //  NOTE: Steady operation only
         label calcFrequency_;
@@ -156,6 +160,9 @@ public:
             //- Return const access to the steady flag
             inline const Switch steadyState() const;
 
+            //- Return const access to the sub cycles
+            inline label subCycles() const;
+
             //- Return const access to the calculation frequency
             inline label calcFrequency() const;
 
diff --git a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H
index 6280b97..ad9e64c 100644
--- a/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H
+++ b/src/lagrangian/intermediate/clouds/Templates/KinematicCloud/cloudSolution/cloudSolutionI.H
@@ -71,6 +71,12 @@ inline const Foam::Switch Foam::cloudSolution::steadyState() const
 }
 
 
+inline Foam::label Foam::cloudSolution::subCycles() const
+{
+    return subCycles_;
+}
+
+
 inline Foam::label Foam::cloudSolution::calcFrequency() const
 {
     return calcFrequency_;
diff --git a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
index 7ec52b1..cbd3417 100644
--- a/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
+++ b/src/lagrangian/intermediate/parcels/Templates/KinematicParcel/KinematicParcel.C
@@ -275,7 +275,7 @@ bool Foam::KinematicParcel<ParcelType>::move
     const scalar maxCo = td.cloud().solution().maxCo();
 
     scalar tEnd = (1.0 - p.stepFraction())*trackTime;
-    const scalar dtMax = tEnd;
+    const scalar dtMax = tEnd/td.cloud().solution().subCycles();
 
     while (td.keepParticle && !td.switchProcessor && tEnd > ROOTVSMALL)
     {

dkxls

2013-08-14 11:52

reporter   ~0002408

Updated the patch to silence -Wignored-qualifiers warnings (i.e. removed to unnecessary 'const')

henry

2016-02-02 21:34

manager   ~0005886

I am looking into this patch but the equivalent functionality is already present in OpenFOAM-dev in the form of maxCo:

    const scalar maxCo = td.cloud().solution().maxCo();

    scalar tEnd = (1.0 - p.stepFraction())*trackTime;
    scalar dtMax = trackTime;
    if (td.cloud().solution().transient())
    {
        dtMax *= maxCo;
    }

dkxls

2016-02-03 12:47

reporter   ~0005892

The max. Courant number definitely imposes a limiting timescales, however there may be cases where this is not sufficient. The Lagrangian timescale for fuel sprays is not only determined by the max. Courant number, but also by the momentum, heat and mass relaxation timescale. Also the droplet breakup timescale should be considered.
In the dieselSpray implementation by Niklas Nordin (e.g. in OpenFOAM 2.0.x) the momentum, heat and mass relaxation timescale were considered together with the option of setting the a minimum number of sub-cycles: https://github.com/OpenFOAM/OpenFOAM-2.0.x/blob/master/src/lagrangian/dieselSpray/parcel/parcel.C#L155
In other Lagrangian spray solvers (e.g. Star-CD), the Lagrangian timescale is similarly determined as:
dt_Lag = min(dt, tau_Co, tau_mom, tau_heat, tau_mass, 0.3*tau_breakup)

To implement this in a similar way is a more extensive task and I understand that it might not be feasible to do this now (or at all). However, the Courant number approach, depends on the droplet velocity, thus my concern was that this approach might allow for larger time steps in cases where velocities are small but e.g. the heat relaxation timescale would set the limiting timescale. The min. sub-cycle parameter, would allow to limit in these cases the max. Lagrangian time-step independent of the velocity.

I already discussed this back in 2013 with Andy Heather, but he refused to implement the sub-cycling as proposed in my patches (but he didn't want to close the bug report either).
Personally, I don't need the sub-cycling any more, because my research interest is in LES of spray flames, which require very small time steps for the Eulerian phase already. Hence, this is mainly concerns unsteady RANS simulations where larger time steps may be used.

henry

2016-02-03 12:59

manager   ~0005893

I don't see much difference between the way the two approaches are implemented. In the case of sub-cycling you divide the dtMax by some number larger than 1 and in the maxCo you multiply dtMax by some number smaller than 1. Under what conditions will the behavior be different?

I agree that the time-step should be limited by the set of physical time-scales as it was done in the dieselSpray library and I am not happy that the replacement library does not include ALL of that functionality and more at the time the dieselSpray library was removed. If you have patches to reintroduce the missing functionality I would be happy to apply them.

dkxls

2016-02-03 13:13

reporter   ~0005895

Arrg, sorry I missed that part!
Indeed the maxCo in OpenFOAM-dev limits the the Lagrangian time scale similarly as the sub-cycling does. (In my defense, this was differently implemented when I reported the bug (i.e. in OpenFOAM 2.2.x)).
Hence, my patch is obsolete and this bug report can be closed.

Regarding the missing functionality compared to the dieselSpray library:
Unfortunately, I don't have patches for this and I am not intending to work on this (my research focus is nowadays more on combustion simulations).

henry

2016-02-03 13:20

manager   ~0005896

OK, thanks for your help and for all the excellent patches and improvements you have provided for OpenFOAM. Please keep contributing and I will endeavour to include them promptly in future.

Issue History

Date Modified Username Field Change
2013-08-12 16:59 dkxls New Issue
2013-08-13 16:38 dkxls Tag Attached: Lagrangian
2013-08-13 16:38 dkxls Tag Attached: spray
2013-08-13 16:38 dkxls Tag Attached: sprayEngineFoam
2013-08-13 16:38 dkxls Tag Attached: sprayFoam
2013-08-13 19:50 dkxls File Added: 0001-Add-subcycles-to-Lagrangian.patch
2013-08-14 11:50 dkxls File Added: 0001-Add-subcycles-to-Lagrangian_v1.patch
2013-08-14 11:52 dkxls Note Added: 0002408
2015-02-15 17:24 wyldckat Tag Attached: contribution
2016-02-02 21:34 henry Note Added: 0005886
2016-02-03 12:47 dkxls Note Added: 0005892
2016-02-03 12:59 henry Note Added: 0005893
2016-02-03 13:13 dkxls Note Added: 0005895
2016-02-03 13:20 henry Note Added: 0005896
2016-02-03 13:21 henry Status new => closed
2016-02-03 13:21 henry Assigned To => henry
2016-02-03 13:21 henry Resolution open => no change required