Sunteți pe pagina 1din 59

English

CFD for Rotating Machinery


OpenFOAM v2.3.0

Keywords
OpenFOAM
SRF
MRF
cyclicAMI
Sliding Interface
Fumiya Nozaki
Last Updated: 22 May 2014

Preface
This document covers

how to set up CFD simulation for a rotating machinery


using OpenFOAM.

In particular,

Single Rotating Frame (SRF)

Multiple Reference Frame (MRF)


Arbitraly Mesh Interface (AMI)
are and will be described in detail.

Chapter 1 Introduction
In this chapter we shall describe the classification of the
methods for solving a flow around a rotating machinery
using OpenFOAM.

What we need to decide


Our simulation begins with deciding the following conditions:

1. Computational Domain

2. Time Dependency

What we need to decide


Our simulation begins with deciding the following conditions:

1. Computational Domain
Does our model include some stationary regions or not?

2. Time Dependency

What we need to decide


Our simulation begins with deciding the following conditions:

1. Computational Domain

2. Time Dependency
Which do we want to obtain, a steady or transient solution?

Classification of methods

2. Time Dependency

1. Computational Domain

Steady

Transient

Only
Rotating
Region

Include
Stationary
Region(s)

SRFSimpleFoam

SimpleFoam
+ fvOptions

Chapter 22
Chapter

Chapter 3

SRFPimpleFoam pimpleDyMFoam
Chapter 22
Chapter

Chapter 4

Chapter 2 Single Rotating Frame


In this chapter we shall describe how to set up the solvers

SRFSimpleFoam

and

SRFPimpleFoam

to simulate an incompressible flow field


in a single rotating frame.

Overview
The Single Rotating Frame (SRF) model computes fluid flow
in a rotating frame of reference that is adhere to a rotating machinery.

Steady-state solutions are possible


Without any mesh motion

OpenFOAM solvers using


Single Rotating Frame (SRF) model
Steady-state solver

SRFSimpleFoam
Transient solver

SRFPimpleFoam

Governing equations
Governing Equations of SRFSimpleFoam
Coriolis force Centrifugal force

+ 2 + = + +
= 0

axis of rotation
Relative velocity
(the velocity viewed from the rotating frame)
angular velocity

= +
position vector

Absolute velocity
(the velocity viewed from the stationary frame)
10

Lets run the tutorials


Tutorials of SRFSimpleFoam and SRFPimpleFoam

SRFSimpleFoam

SRFPimpleFoam

11

mixer tutorial | Computational domain


tutorials/incompressible/SRFSimpleFoam/mixer
A blade named innerWall is rotating counterclockwise at 5000 rpm.
outerWall

outlet

cyclic_half1

cyclic_half0

innerWall

inlet patch is hidden for facilitating visualization.


inlet

12

mixer tutorial | Boundary conditions


Boundary conditions of velocity field
outerWall
inlet

Stationary wall

Fixed absolute velocity

= 0 0 10

cyclic_half1
cyclic_half0

innerWall
Rotating wall =

Cyclic boundary condition


13

mixer tutorial | Case structure

SRFSimpleFoam

case

constant
Urel

system
RASProperties

controlDict

transportProperties

SRFProperties

omega

fvSolution

polyMesh

nut

fvSchemes

boundary
faces
neighbour
owner

Pay attention to these files!

points

Urel represents the relative velocity.


Rotating velocity condition is described in SRFProperties file.
14

SRFProperties
Angular velocity condition is described in SRFProperties file.
/*--------------------------------*- C++ -*----------------------------------*
| ========= | |
| / F ield | OpenFOAM: The Open Source CFD Toolbox |
| / O peration | Version: 2.3.0 |
| / A nd | Web: www.OpenFOAM.org |
| / M anipulation | |
*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object SRFProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
SRFModel rpm;
axis ( 0 0 1 );
rpmCoeffs
{
rpm 5000;
}

Angular velocity is specified


in terms of revolutions-per-minute [rpm]

Axis of rotation
5000 rpm 5000 2 60 = 523.6 [rad/s]

// ************************************************************************* //

Rotational direction
When the axis vector points to you
rpm>0 rotation in counterclockwise direction
rpm<0 rotation in clockwise direction

15

Urel
In this tutorialSRFVelocity boundary condition is used on inlet
and outerWall boundaries.
inlet
{
type
inletValue
relative
value
}

SRFVelocity;
uniform (0 0 -10);
no;
uniform (0 0 0);

By setting relative up as no

This means = 0 0 10 .

outerWall
{
type
inletValue
relative
value
}

SRFVelocity;
uniform (0 0 0);
no;
uniform (0 0 0);

Boundary condition of
the relative velocity (Urel)
is able to be specified
in terms of the absolute velocity.

This means = (a stationary wall).


16

Closer look at the velocity on outerWall

In the stationary coordinate system

In the rotating coordinate system


Vectors show

Radius of outerWall is 0.1 m

=
= 523.6 0.1 = 52.36 [/]
Rotational direction
17

Lets run the tutorials


Tutorials of SRFSimpleFoam and SRFPimpleFoam

SRFSimpleFoam

SRFPimpleFoam

18

rotor2D tutorial | Computational domain


tutorials/incompressible/SRFPimpleFoam/rotor2D
A wall named rotor is rotating counterclockwise at 60 rpm.

0.2m
rotor

freestream

19

rotor2D tutorial | Boundary conditions


Boundary conditions of velocity field

rotor

Rotating wall

freestream

20

Implementation | Calculation of additional forces and absolute velocity

Calculation of the additional force terms

+ 2 + = + +
= 0

UrelEqn.H

// Relative momentum predictor

SRFModel.H

tmp<fvVectorMatrix> UrelEqn
(
fvm::div(phi, Urel)
+ turbulence->divDevReff(Urel)

Foam::tmp<Foam::DimensionedField<Foam::vector, Foam::volMesh> >


Foam::SRF::SRFModel::Su() const
{

+ SRF->Su()
==

return Fcoriolis() + Fcentrifugal();

fvOptions(Urel)

);

l.126

l.147

2.0*omega_ ^ Urel_

omega_ ^ (omega_ ^ mesh_.C())

Calculation of the absolute velocity (Uabs)


SRFSimpleFoam.C
Urel + SRF->U()

omega_ ^ (mesh_.C() - axis_*(axis_ & mesh_.C()))


21

Implementation | SRFVelocity
void Foam::SRFVelocityFvPatchVectorField::updateCoeffs()
{
if (updated())
{
return;
}

// If not relative to the SRF include the effect of the SRF


if (!relative_)
If relative is
{
// Get reference to the SRF model
const SRF::SRFModel& srf =
db().lookupObject<SRF::SRFModel>("SRFProperties");
// Determine patch velocity due to SRF

no

Calculate

const vectorField SRFVelocity(srf.velocity(patch().Cf()));

SRFModel.C l.60

operator==(-SRFVelocity + inletValue_); = +

}
// If already relative to the SRF simply supply the inlet value as a fixed
// value
else
If relative is yes
{
operator==(inletValue_);
}
fixedValueFvPatchVectorField::updateCoeffs();
}

22

Chapter 3 Multiple Reference Frame


In this chapter we shall describe how to set up
the multiple reference frame simulation in OpenFOAM.
This model is activated using
fvOptions functionality.

23

Overview
The Multiple Reference Frame (SRF) model computes fluid flow
using both the rotating and stationary reference frame.

Rotating zone is solved in the rotating frame


Stationary zone is solved in the stationary frame

Multiple frames

OpenFOAM solvers using


Multiple Reference Frame (MRF) model
Steady-state solver

simpleFoam

fvOptions
+

MRFSource

24

Conceptual image

Rotating
zone

Stationary
zone

25

Governing equations
Governing equations
Rotating zone

1 Coriolis force

= + +
= 0

Stationary zone

= + +
=0

In a rotating zone
1 the Coriolis force is added to the governing equations

2 the flux is calculated from the relative velocity


26

mixerVessel2D tutorial | Computational domain


tutorials/incompressible/simpleFoam/mixerVessel2D
A wall named rotor is rotating counterclockwise at 104.72 rad/s.

stator
0.1m

0.04m

rotor

27

mixerVessel2D tutorial | Rotating zone

Rotating
zone
0.12m

Stationary
zone

28

mixerVessel2D tutorial | Boundary condition

stator
Stationary wall

rotor
Rotating wall

29

mixerVessel2D tutorial | Case structure


case

constant

system

RASProperties

controlDict

transportProperties

fvSchemes

polyMesh

fvSolution

epsilon

boundary

nut

faces

fvOptions

neighbour
owner
points
cellZones
30

fvOptions
MRF1
{
type
active
selectionMode
cellZone

MRFSource;
ture;
cellZone;
rotor;

MRFSourceCoeffs
{
origin
(0 0 0);
axis
(0 0 1);
omega
104.72;
}
Unit: [rad/s]

Following options are available for


selectionMode
all
cellSet
cellZone
mapRegion
points

Specifying the rotating zone


by cellZone named rotor.

axis

origin

31

What is cellZones?
FoamFile
constant/polyMesh/cellZones
{
version
2.0;
format
ascii;
class
regIOobject;
location
"constant/polyMesh";
object
cellZones;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

The number of cellZones

1
(
The name of cellZones
rotor
{
type cellZone;
cellLabels
List<label>
1536
The number of cells
(
that make up cellZones
0
1
2
3
(snip)
1533
List of their cell labels
1534
1535
)
;
}
)

rotor

// ************************************************************************* //

32

Implementation | Calculation of Coriolis force


MRFZone.C
355
356
357
358
359
360
361

void Foam::MRFZone::addCoriolis(fvVectorMatrix& UEqn, const bool rhs) const


{
if (cellZoneID_ == -1)
{
return;
}

362

const labelList& cells = mesh_.cellZones()[cellZoneID_];

363

const scalarField& V = mesh_.V();

364

vectorField& Usource = UEqn.source();

365
366

const vectorField& U = UEqn.psi();

367
368

const vector Omega = this->Omega();

369
370

if (rhs)
{

371
372

forAll(cells, i)
{

373

Adding the Coriolis force


as a source term

label celli = cells[i];

374
375
376
377
378

Usource[celli] += V[celli]*(Omega ^ U[celli]);


}
}
else
{

379
380

forAll(cells, i)
{

381
382
383
384
385

List of cell labels


included in cellZones

label celli = cells[i];


Usource[celli] -= V[celli]*(Omega ^ U[celli]);
}
}
}

33

Implementation | Calculation of relative flux


MRFZoneTemplates.C

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

template<class RhoFieldType>
void Foam::MRFZone::makeRelativeRhoFlux
(
const RhoFieldType& rho,
surfaceScalarField& phi
) const
{
const surfaceVectorField& Cf = mesh_.Cf();
const surfaceVectorField& Sf = mesh_.Sf();
const vector Omega = omega_->value(mesh_.time().timeOutputValue())*axis_;
const vectorField& Cfi = Cf.internalField();
const vectorField& Sfi = Sf.internalField();
scalarField& phii = phi.internalField();
// Internal faces
forAll(internalFaces_, i)
{
label facei = internalFaces_[i];
phii[facei] -= rho[facei]*(Omega ^ (Cfi[facei] - origin_)) & Sfi[facei];
}
makeRelativeRhoFlux(rho.boundaryField(), phi.boundaryField());
}

Making the relative flux by subtracting from the absolute flux


34

Chapter 4 Dynamic Mesh


In this chapter we shall describe how to set up
a transient simulation with mesh motion in OpenFOAM.

35

mixerVesselAMI2D tutorial | Computational domain


First run the tutorial and enjoy post-processing:
incompressible/pimpleDyMFoam/mixerVesselAMI2D

Static Pressure
t=5.90 s
36

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.90 s
37

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.905 s
38

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.91 s
39

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.915 s
40

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.92 s
41

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.925 s
42

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.93 s
43

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.935 s
44

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.94 s
45

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.945 s
46

mixerVesselAMI2D tutorial | Results

Velocity Magnitude
t=5.95 s
47

mixerVesselAMI2D tutorial | Mesh motion

Mesh is stationary

Mesh is in rotating motion

Settings are in the next page.


48

dynamicMeshDict

FoamFile
{
version
2.0;
format
ascii;
class
dictionary;
location
"constant";
object
dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMesh

solidBodyMotionFvMesh;

cellZone: rotor

motionSolverLibs ( "libfvMotionSolvers.so" );

solidBodyMotionFvMeshCoeffs
{
cellZone
rotor;

solidBodyMotionFunction rotatingMotion;
rotatingMotionCoeffs
{
origin
(0 0 0);
The cellZone rotor is rotating
axis
(0 0 1);
counterclockwise at 6.2832 rad/s
omega
6.2832; // rad/s
}
about the origin.

49

Sliding interface capability

Patch: AMI1

Coupled
through
cyclicAMI

Patch: AMI2

rotating

stationary
50

cyclicAMI

constant/polyMesh/boundary file
nFaces
startFace

192;
6048;

type
inGroups
nFaces
startFace
matchTolerance
transform
neighbourPatch

cyclicAMI;
1(cyclicAMI);
96;
6240;
0.0001;
noOrdering;
AMI2;

type
inGroups
nFaces
startFace
matchTolerance
transform
neighbourPatch

cyclicAMI;
1(cyclicAMI);
96;
6336;
0.0001;
noOrdering;
AMI1;

}
AMI1
{

}
AMI2
{

}
front
{
type
inGroups

Sliding interface capability , e.g. for


rotating machinery is available using
cyclicAMI boundary patch class.

In neighbourPatch, the coupled


patch name is specified.

empty;
1(empty);

51

Appendix

52

AMI1
{
type
inGroups
nFaces
startFace
neighbourPatch
transform

cyclicAMI;
1 (cyclicAMI);
20;
2440;
AMI2;
noOrdering;

type
inGroups
nFaces
startFace
neighbourPatch
transform

cyclicAMI;
1 (cyclicAMI);
40;
2460;
AMI1;
noOrdering;

}
AMI2
{

AMI1

AMI2

Coupled
through
cyclicAMI
53

Lets check the weights!


AMI: Creating addressing and weights between 20 source faces and 40 target faces
AMI: Patch source sum(weights) min/max/average = 1, 1, 1
AMI: Patch target sum(weights) min/max/average = 1, 1, 1

sum(weights)=1 is the ideal value.


This means the patches conform perfectly.
AMI1
{

type
inGroups
nFaces
startFace
neighbourPatch
transform

cyclicAMI;
1 (cyclicAMI);
20;
2440;
AMI2;
noOrdering;

type
inGroups
nFaces
startFace
neighbourPatch
transform

cyclicAMI;
1 (cyclicAMI);
40;
2460;
AMI1;
noOrdering;

source patch

Appearing first
in boundary file

AMI2
{

target patch

54

Translate the pink-colored volume upward by 0.02m

55

Lets recheck the weights!


AMI: Creating addressing and weights between 20 source faces and 40 target faces
AMI: Patch source sum(weights) min/max/average = 0.6, 1, 0.98
AMI: Patch target sum(weights) min/max/average = 0.2, 1, 0.98

Fraction of
the intersecting areas

0.052

0.032

0.03
() =
= 0.6
0.05
56

Lets recheck the weights!


AMI: Creating addressing and weights between 20 source faces and 40 target faces
AMI: Patch source sum(weights) min/max/average = 0.6, 1, 0.98
AMI: Patch target sum(weights) min/max/average = 0.2, 1, 0.98

0.0252

0.0052

0.005
= 0.2
0.025

57

Release note Version2.3.0

User specified threshold for sum(weights)

58

Thank
You!
Kindly let me know
if you have trouble downloading this slide.
59

S-ar putea să vă placă și