Skip to content

Commit f1481d5

Browse files
Merge pull request #48 from mattfalcone1997/cfl_time_stepper
Add time stepper that allows OpenFOAM to control the time step so that CFL adaptive stepping can be used
2 parents b3ba1b8 + f6e798f commit f1481d5

File tree

52 files changed

+39383
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+39383
-2
lines changed

include/base/FoamSolver.h

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,38 @@
11
#pragma once
22

3-
#include "fvCFD_moose.h"
3+
#include "solver.H"
4+
#include "functionObject.H"
45

56
#include <vector>
67

8+
namespace Foam
9+
{
10+
namespace functionObjects
11+
{
12+
// Function object to tell OpenFOAM what MOOSE's dt is
13+
class mooseDeltaT : public functionObject
14+
{
15+
private:
16+
const scalar & dt_;
17+
18+
public:
19+
TypeName("mooseDeltaT");
20+
mooseDeltaT(const word & name, const Time & runTime, const scalar & dt)
21+
: functionObject(name, runTime), dt_(dt)
22+
{
23+
}
24+
25+
wordList fields() const { return wordList::null(); }
26+
27+
bool executeAtStart() const { return false; }
28+
29+
bool execute() { return true; }
30+
bool write() { return true; }
31+
scalar maxDeltaT() const { return dt_; }
32+
};
33+
}
34+
}
35+
736
namespace Hippo
837
{
938

@@ -32,6 +61,19 @@ class FoamSolver
3261
void setCurrentTime(double time) { runTime().setTime(time, runTime().timeIndex()); }
3362
// Set the time at which the solver should terminate.
3463
void setEndTime(double time) { runTime().setEndTime(time); }
64+
// Run the presolve from MOOSE objects.
65+
void preSolve();
66+
// Provide access to the openfoam solver.
67+
Foam::solver & solver() { return *_solver; };
68+
// Calculate OpenFOAM's time step.
69+
Foam::scalar computeDeltaT();
70+
// check whether OpenFOAM has variable time step.
71+
bool isDeltaTAdjustable() const;
72+
// creates function object that tells OpenFOAM what MOOSE's
73+
// time step is.
74+
void appendDeltaTFunctionObject(const Foam::scalar & dt);
75+
// get the current deltaT.
76+
Foam::scalar getTimeDelta() { return runTime().deltaTValue(); };
3577

3678
private:
3779
Foam::solver * _solver = nullptr;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#pragma once
2+
3+
#include "FoamProblem.h"
4+
#include "FoamSolver.h"
5+
6+
#include <InputParameters.h>
7+
#include <TimeStepper.h>
8+
9+
/*
10+
Time stepper that allows OpenFOAM to control the time step enabling features such as CFL
11+
daptive time steps. The intention is to allows the current time step in OpenFOAM
12+
to be exposed to MOOSE
13+
*/
14+
15+
class FoamControlledTimeStepper : public TimeStepper
16+
{
17+
public:
18+
FoamControlledTimeStepper(InputParameters const & params);
19+
static InputParameters validParams();
20+
21+
// Get initial time step from OpenFOAM input file
22+
virtual Real computeInitialDT() { return computeDT(); };
23+
24+
/* Read time step from OpenFOAM
25+
- Make sure the time step duration is computed in the current step
26+
*/
27+
virtual Real computeDT();
28+
29+
// Consider how to communicate starting time for this stepper
30+
// e.g. after a restart this would need to be executed after the
31+
// OpenFOAM restart.
32+
virtual void init();
33+
34+
private:
35+
// These two variables are needed depending on how the time-stepper is initialised
36+
Hippo::FoamSolver & solver() { return problem()->solver(); }
37+
FoamProblem * problem();
38+
// Variables to determine whether an adjustable time step is used in OF and
39+
// what it is.
40+
bool _dt_adjustable = false;
41+
Real _foam_initial_dt = 0.;
42+
};

src/base/FoamSolver.C

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@
1111
#include <cassert>
1212
#include <iterator>
1313

14+
namespace Foam
15+
{
16+
namespace functionObjects
17+
{
18+
defineTypeNameAndDebug(mooseDeltaT, 0);
19+
20+
}
21+
}
22+
1423
namespace Hippo
1524
{
1625
namespace
@@ -91,7 +100,6 @@ FoamSolver::run()
91100

92101
// Adjust the time-step according to the solver maxDeltaT
93102
adjustDeltaT(time, solver);
94-
95103
time++;
96104

97105
// TODO: replace std::cout with MOOSE output or a dependency-injected stream.
@@ -206,4 +214,36 @@ FoamSolver::wallHeatFlux(const int patch_id, std::vector<double> & fill_vector)
206214
return whf_boundary.size();
207215
}
208216

217+
void
218+
FoamSolver::preSolve()
219+
{
220+
_solver->pimple.readIfModified();
221+
_solver->preSolve();
222+
}
223+
224+
Foam::scalar
225+
FoamSolver::computeDeltaT()
226+
{
227+
// This code has been adapted from OpenFOAM's adjustDeltaT to determine the time-step that
228+
// OpenFOAM will use on the next time step so MOOSE can predict it.
229+
Foam::scalar deltaT =
230+
std::min(_solver->maxDeltaT(), _solver->runTime.functionObjects().maxDeltaT());
231+
232+
if (deltaT < Foam::rootVGreat)
233+
return std::min(Foam::solver::deltaTFactor * _solver->runTime.deltaTValue(), deltaT);
234+
return _solver->runTime.deltaTValue();
235+
}
236+
237+
bool
238+
FoamSolver::isDeltaTAdjustable() const
239+
{
240+
return _solver->runTime.controlDict().lookupOrDefault("adjustTimeStep", false);
241+
}
242+
243+
void
244+
FoamSolver::appendDeltaTFunctionObject(const Foam::scalar & dt)
245+
{
246+
runTime().functionObjects().append(
247+
new Foam::functionObjects::mooseDeltaT("Moose time step", runTime(), dt));
248+
}
209249
} // namespace Hippo

src/problems/FoamProblem.C

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ FoamProblem::externalSolve()
112112
{
113113
if (parameters().get<bool>("solve"))
114114
{
115+
_solver.setTimeDelta(_dt); // Needed for constant deltaT cases
115116
_solver.run();
116117
}
117118
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "FoamProblem.h"
2+
#include "FoamControlledTimeStepper.h"
3+
#include <pimpleSingleRegionControl.H>
4+
5+
#include <scalar.H>
6+
#include <TimeStepper.h>
7+
#include <Transient.h>
8+
9+
registerMooseObject("hippoApp", FoamControlledTimeStepper);
10+
11+
InputParameters
12+
FoamControlledTimeStepper::validParams()
13+
{
14+
auto params = TimeStepper::validParams();
15+
return params;
16+
}
17+
18+
FoamControlledTimeStepper::FoamControlledTimeStepper(InputParameters const & params)
19+
: TimeStepper(params)
20+
{
21+
auto problem = dynamic_cast<FoamProblem *>(&_app.feProblem());
22+
if (!problem)
23+
{
24+
mooseError("FoamTimeStepper expects to be used with FoamProblem");
25+
}
26+
}
27+
28+
Real
29+
FoamControlledTimeStepper::computeDT()
30+
{
31+
32+
if (!_dt_adjustable)
33+
return _foam_initial_dt;
34+
35+
// Not ideal, but for MOOSE to get an accurate deltaT
36+
// preSolve must be called as this updates the BCs.
37+
solver().preSolve();
38+
39+
// Ensure MOOSE gets OpenFOAM's time step unaffected by the mooseDeltaT
40+
// functionObject.
41+
Real dt_tmp = _dt;
42+
_dt = Foam::rootVGreat;
43+
44+
// compute OpenFOAM's desired time step
45+
Real deltaT = solver().computeDeltaT();
46+
47+
// reset MOOSE's time step and return
48+
_dt = dt_tmp;
49+
return deltaT;
50+
}
51+
52+
FoamProblem *
53+
FoamControlledTimeStepper::problem()
54+
{
55+
auto problem = dynamic_cast<FoamProblem *>(&_app.feProblem());
56+
if (!problem)
57+
{
58+
mooseError("FoamTimeStepper expects to be used with FoamProblem");
59+
}
60+
return problem;
61+
}
62+
63+
void
64+
FoamControlledTimeStepper::init()
65+
{
66+
TimeStepper::init();
67+
68+
// determine if OpenFOAM's time-step is adjustable in controlDict
69+
_dt_adjustable = solver().isDeltaTAdjustable();
70+
71+
// The key idea is that runTime.functionObjects().maxDeltaT() in adjustDeltaT
72+
// loops over the function objects and chooses the minimum, so by having
73+
// a function Object that returns what MOOSE wants, OpenFOAM will use the
74+
// MOOSE time step if it is smaller than what OpenFOAM wants. As a result,
75+
// if MOOSE wants to add a synchronisation step OpenFOAM will also use it too.
76+
77+
// create function object and append it to the solver's function object list
78+
solver().appendDeltaTFunctionObject(_dt);
79+
80+
if (!_dt_adjustable)
81+
_foam_initial_dt = solver().getTimeDelta();
82+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*--------------------------------*- C++ -*----------------------------------*\
2+
========= |
3+
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4+
\\ / O peration | Website: https://openfoam.org
5+
\\ / A nd | Version: 10
6+
\\/ M anipulation |
7+
\*---------------------------------------------------------------------------*/
8+
FoamFile
9+
{
10+
format ascii;
11+
class volScalarField;
12+
location "0";
13+
object T;
14+
}
15+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
16+
17+
dimensions [0 0 0 1 0 0 0];
18+
19+
internalField uniform 300;
20+
21+
boundaryField
22+
{
23+
inlet
24+
{
25+
type fixedValue;
26+
value uniform 300;
27+
}
28+
outlet
29+
{
30+
type zeroGradient;
31+
}
32+
top
33+
{
34+
type zeroGradient;
35+
}
36+
slip-bottom
37+
{
38+
type zeroGradient;
39+
}
40+
bottom
41+
{
42+
type zeroGradient;
43+
}
44+
interface
45+
{
46+
type fixedGradient;
47+
gradient uniform 0;
48+
}
49+
defaultFaces
50+
{
51+
type empty;
52+
}
53+
}
54+
55+
56+
// ************************************************************************* //
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*--------------------------------*- C++ -*----------------------------------*\
2+
========= |
3+
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4+
\\ / O peration | Website: https://openfoam.org
5+
\\ / A nd | Version: 10
6+
\\/ M anipulation |
7+
\*---------------------------------------------------------------------------*/
8+
FoamFile
9+
{
10+
format ascii;
11+
class volVectorField;
12+
location "0";
13+
object U;
14+
}
15+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
16+
17+
dimensions [0 1 -1 0 0 0 0];
18+
19+
internalField uniform (0.1 0 0);
20+
21+
boundaryField
22+
{
23+
inlet
24+
{
25+
type fixedValue;
26+
value uniform (0.1 0 0);
27+
}
28+
outlet
29+
{
30+
type zeroGradient;
31+
}
32+
top
33+
{
34+
type slip;
35+
}
36+
slip-bottom
37+
{
38+
type slip;
39+
}
40+
bottom
41+
{
42+
type noSlip;
43+
}
44+
interface
45+
{
46+
type noSlip;
47+
}
48+
defaultFaces
49+
{
50+
type empty;
51+
}
52+
}
53+
54+
55+
// ************************************************************************* //

0 commit comments

Comments
 (0)