CFD for Rotating Machinery using OpenFOAM

Post on 06-May-2015

11.150 views 133 download

Transcript of CFD for Rotating Machinery using OpenFOAM

Keywords: • OpenFOAM • SRF • MRF • cyclicAMI • Sliding Interface

Fumiya Nozaki

Last Updated: 22 May 2014

English

CFD for Rotating Machinery

OpenFOAM v2.3.0

2

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.

3

Chapter 1 Introduction

In this chapter we shall describe the classification of the methods for solving a flow around a rotating machinery

using OpenFOAM.

4

What we need to decide

Our simulation begins with deciding the following conditions:

1. Computational Domain

2. Time Dependency

5

What we need to decide

Our simulation begins with deciding the following conditions:

1. Computational Domain

2. Time Dependency

Does our model include some stationary regions or not?

6

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?

7

Classification of methods

Only Rotating Region

Include Stationary Region(s)

Steady SRFSimpleFoam

Chapter 2

SimpleFoam + fvOptions

Transient SRFPimpleFoam

Chapter 2

pimpleDyMFoam

1. Computational Domain 2.Tim

e D

ependency

Chapter 2

Chapter 2

Chapter 3

Chapter 4

8

Chapter 2 Single Rotating Frame

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

and

to simulate an incompressible flow field

in a single rotating frame.

SRFSimpleFoam SRFPimpleFoam

9

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

SRFSimpleFoam

SRFPimpleFoam

Steady-state solver

Transient solver

10

Governing equations

Governing Equations of SRFSimpleFoam

𝒖𝑅 ∙ 𝛻 𝒖𝑅 + 2𝜴 × 𝒖𝑅 + 𝜴× 𝜴 × 𝒓 = −𝛻𝑝 + 𝛻 ∙ 𝜈𝑒𝑓𝑓 𝛻𝒖𝑅 + 𝛻𝒖𝑅

𝑇

𝛻 ∙ 𝒖𝑅 = 0

𝒖 = 𝒖𝑅 + 𝜴 × 𝒓

𝜴 :angular velocity

axis of rotation

𝒓

Absolute velocity (the velocity viewed from the stationary frame)

Relative velocity (the velocity viewed from the rotating frame)

:position vector

Coriolis force Centrifugal force

11

Let’s run the tutorials

Tutorials of SRFSimpleFoam and SRFPimpleFoam

• SRFSimpleFoam • SRFPimpleFoam

12

mixer tutorial | Computational domain

tutorials/incompressible/SRFSimpleFoam/mixer

A blade named “innerWall” is rotating counterclockwise at 5000 rpm.

outlet

outerWall

innerWall

cyclic_half1 cyclic_half0

“inlet” patch is hidden for facilitating visualization. inlet

13

mixer tutorial | Boundary conditions

cyclic_half1

cyclic_half0

Cyclic boundary condition

innerWall

𝒖𝑅 = 𝟎

outerWall

𝒖 = 𝟎

inlet

𝒖 = 0 0 − 10

Fixed absolute velocity

Boundary conditions of velocity field

Rotating wall

Stationary wall

14

mixer tutorial | Case structure

transportProperties

polyMesh

RASProperties

system constant 0

controlDict

fvSchemes

fvSolution

boundary

faces

neighbour

owner

points

Urel

p

k

omega

nut

case

SRFProperties

Pay attention to these files!

• “Urel” represents the relative velocity. • Rotating velocity condition is described in “SRFProperties” file.

SRFSimpleFoam

15

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]

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

Rotational direction

16

Urel

In this tutorial,”SRFVelocity” boundary condition is used on inlet and outerWall boundaries.

inlet

{

type SRFVelocity;

inletValue uniform (0 0 -10);

relative no;

value uniform (0 0 0);

}

This means 𝒖 = 𝟎 (a stationary wall).

This means 𝒖 = 0 0 − 10 .

By setting “relative” up as ”no”

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

outerWall

{

type SRFVelocity;

inletValue uniform (0 0 0);

relative no;

value uniform (0 0 0);

}

17

Closer look at the velocity on outerWall

In the stationary coordinate system

In the rotating coordinate system

Radius of outerWall is 0.1 m

𝒖 = 𝟎

𝒖𝒓 = 𝒖 − 𝛀 × 𝒓

= 523.6 ∙ 0.1 = 52.36 [𝑚/𝑠]

Vectors show 𝒖𝑟

Rotational direction

18

Let’s run the tutorials

Tutorials of SRFSimpleFoam and SRFPimpleFoam

• SRFSimpleFoam • SRFPimpleFoam

19

rotor2D tutorial | Computational domain

tutorials/incompressible/SRFPimpleFoam/rotor2D

A wall named “rotor” is rotating counterclockwise at 60 rpm.

rotor

freestream

0.2m

20

rotor2D tutorial | Boundary conditions

Boundary conditions of velocity field

rotor

freestream

𝒖𝑅 = 𝟎

Rotating wall

21

Implementation | Calculation of additional forces and absolute velocity

𝒖𝑅 ∙ 𝛻 𝒖𝑅 + 2𝜴 × 𝒖𝑅 + 𝜴× 𝜴 × 𝒓 = −𝛻𝑝 + 𝛻 ∙ 𝜈𝑒𝑓𝑓 𝛻𝒖𝑅 + 𝛻𝒖𝑅

𝑇

𝛻 ∙ 𝒖𝑅 = 0

// Relative momentum predictor

tmp<fvVectorMatrix> UrelEqn (

fvm::div(phi, Urel)

+ turbulence->divDevReff(Urel)

+ SRF->Su() ==

fvOptions(Urel) );

UrelEqn.H

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

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

return Fcoriolis() + Fcentrifugal(); }

SRFModel.H

2.0*omega_ ^ Urel_ omega_ ^ (omega_ ^ mesh_.C())

l.126 l.147

Calculation of the absolute velocity (Uabs)

Urel + SRF->U()

SRFSimpleFoam.C

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

Calculation of the additional force terms

22

Implementation | SRFVelocity

void Foam::SRFVelocityFvPatchVectorField::updateCoeffs()

{

if (updated())

{

return;

}

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

if (!relative_)

{

// Get reference to the SRF model

const SRF::SRFModel& srf =

db().lookupObject<SRF::SRFModel>("SRFProperties");

// Determine patch velocity due to SRF

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

operator==(-SRFVelocity + inletValue_);

}

// If already relative to the SRF simply supply the inlet value as a fixed

// value

else

{

operator==(inletValue_);

}

fixedValueFvPatchVectorField::updateCoeffs();

}

If ”relative” is ”no”

SRFModel.C l.60 Calculate 𝜴 × 𝒓

𝒖𝑅 = −𝜴 × 𝒓 + 𝒖

If ”relative” is ”yes”

23

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.

24

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

simpleFoam

Steady-state solver

MRFSource +

fvOptions

OpenFOAM solvers using Multiple Reference Frame (MRF) model

Multiple frames

25

Conceptual image

Rotating zone

Stationary zone

26

Governing equations

𝒖𝑅 ∙ 𝛻 𝒖 − 𝛀 × 𝒖 = −𝛻𝑝 + 𝛻 ∙ 𝜈𝑒𝑓𝑓 𝛻𝒖 + 𝛻𝒖 𝑇

𝛻 ∙ 𝒖𝑅 = 0

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

• the flux is calculated from the relative velocity 𝒖𝑅

Governing equations

Coriolis force

𝒖 ∙ 𝛻 𝒖 − 𝛀 × 𝒖 = −𝛻𝑝 + 𝛻 ∙ 𝜈𝑒𝑓𝑓 𝛻𝒖 + 𝛻𝒖 𝑇

𝛻 ∙ 𝒖 = 0

Rotating zone

Stationary zone

1

2

1

2

27

mixerVessel2D tutorial | Computational domain

tutorials/incompressible/simpleFoam/mixerVessel2D

A wall named “rotor” is rotating counterclockwise at 104.72 rad/s.

rotor

stator

0.1m

0.04m

28

mixerVessel2D tutorial | Rotating zone

Rotating zone

Stationary zone

0.12m

29

mixerVessel2D tutorial | Boundary condition

Rotating wall

rotor

stator

Stationary wall

30

mixerVessel2D tutorial | Case structure

transportProperties

polyMesh

RASProperties

system constant 0

controlDict

fvSchemes

fvSolution

fvOptions boundary

faces

neighbour

owner

points

cellZones

U

p

k

epsilon

nut

case

Pay attention to these files!

• “Urel” represents the relative velocity. • Rotating velocity condition is described in “SRFProperties” file.

31

fvOptions

MRF1

{

type MRFSource;

active ture;

selectionMode cellZone;

cellZone rotor;

MRFSourceCoeffs

{

origin (0 0 0);

axis (0 0 1);

omega 104.72;

}

}

Specifying the rotating zone by cellZone named rotor.

Unit: [rad/s]

axis

Following options are available for “selectionMode” • all • cellSet • cellZone • mapRegion • points

origin

32

What is cellZones?

FoamFile

{

version 2.0;

format ascii;

class regIOobject;

location "constant/polyMesh";

object cellZones;

}

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

1

(

rotor

{

type cellZone;

cellLabels List<label>

1536

(

0

1

2

3

(snip)

1533

1534

1535

)

;

}

)

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

The number of cellZones

The name of cellZones

The number of cells that make up cellZones “rotor”

List of their cell labels

constant/polyMesh/cellZones

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

356 {

357 if (cellZoneID_ == -1)

358 {

359 return;

360 }

361

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

363 const scalarField& V = mesh_.V();

364 vectorField& Usource = UEqn.source();

365 const vectorField& U = UEqn.psi();

366

367 const vector Omega = this->Omega();

368

369 if (rhs)

370 {

371 forAll(cells, i)

372 {

373 label celli = cells[i];

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

375 }

376 }

377 else

378 {

379 forAll(cells, i)

380 {

381 label celli = cells[i];

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

383 }

384 }

385 }

33

Implementation | Calculation of Coriolis force

MRFZone.C

List of cell labels included in cellZones

Adding the Coriolis force as a source term

34

Implementation | Calculation of relative flux

34 template<class RhoFieldType>

35 void Foam::MRFZone::makeRelativeRhoFlux

36 (

37 const RhoFieldType& rho,

38 surfaceScalarField& phi

39 ) const

40 {

41 const surfaceVectorField& Cf = mesh_.Cf();

42 const surfaceVectorField& Sf = mesh_.Sf();

43

44 const vector Omega = omega_->value(mesh_.time().timeOutputValue())*axis_;

45

46 const vectorField& Cfi = Cf.internalField();

47 const vectorField& Sfi = Sf.internalField();

48 scalarField& phii = phi.internalField();

49

50 // Internal faces

51 forAll(internalFaces_, i)

52 {

53 label facei = internalFaces_[i];

54 phii[facei] -= rho[facei]*(Omega ^ (Cfi[facei] - origin_)) & Sfi[facei];

55 }

56

57 makeRelativeRhoFlux(rho.boundaryField(), phi.boundaryField());

58 }

MRFZoneTemplates.C

Making the relative flux by subtracting 𝜴 × 𝒓 ∙ 𝑺𝑓 from the absolute flux

35

Chapter 4 Dynamic Mesh

In this chapter we shall describe how to set up

a transient simulation with mesh motion in OpenFOAM.

36

mixerVesselAMI2D tutorial | Computational domain

First run the tutorial and enjoy post-processing:

incompressible/pimpleDyMFoam/mixerVesselAMI2D

Static Pressure t=5.90 s

37

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.90 s

38

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.905 s

39

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.91 s

40

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.915 s

41

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.92 s

42

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.925 s

43

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.93 s

44

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.935 s

45

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.94 s

46

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.945 s

47

mixerVesselAMI2D tutorial | Results

Velocity Magnitude t=5.95 s

48

mixerVesselAMI2D tutorial | Mesh motion

Mesh is in rotating motion

Mesh is stationary

Settings are in the next page.

49

dynamicMeshDict

FoamFile

{

version 2.0;

format ascii;

class dictionary;

location "constant";

object dynamicMeshDict;

}

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

dynamicFvMesh solidBodyMotionFvMesh;

motionSolverLibs ( "libfvMotionSolvers.so" );

solidBodyMotionFvMeshCoeffs

{

cellZone rotor;

solidBodyMotionFunction rotatingMotion;

rotatingMotionCoeffs

{

origin (0 0 0);

axis (0 0 1);

omega 6.2832; // rad/s

}

}

cellZone: rotor

The cellZone “rotor” is rotating counterclockwise at 6.2832 rad/s about the origin.

50

Sliding interface capability

Patch: AMI1

Patch: AMI2

Coupled through

“cyclicAMI “

stationary

rotating

51

cyclicAMI

nFaces 192;

startFace 6048;

}

AMI1

{

type cyclicAMI;

inGroups 1(cyclicAMI);

nFaces 96;

startFace 6240;

matchTolerance 0.0001;

transform noOrdering;

neighbourPatch AMI2;

}

AMI2

{

type cyclicAMI;

inGroups 1(cyclicAMI);

nFaces 96;

startFace 6336;

matchTolerance 0.0001;

transform noOrdering;

neighbourPatch AMI1;

}

front

{

type empty;

inGroups 1(empty);

constant/polyMesh/boundary file

Sliding interface capability , e.g. for rotating machinery is available using cyclicAMI boundary patch class.

In “neighbourPatch”, the coupled patch name is specified.

52

Appendix

53

AMI1

{

type cyclicAMI;

inGroups 1 (cyclicAMI);

nFaces 20;

startFace 2440;

neighbourPatch AMI2;

transform noOrdering;

}

AMI2

{

type cyclicAMI;

inGroups 1 (cyclicAMI);

nFaces 40;

startFace 2460;

neighbourPatch AMI1;

transform noOrdering;

}

AMI1 AMI2

Coupled through

“cyclicAMI “

54

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

Let’s check the weights!

sum(weights)=1 is the ideal value. This means the patches conform perfectly.

AMI1

{

type cyclicAMI;

inGroups 1 (cyclicAMI);

nFaces 20;

startFace 2440;

neighbourPatch AMI2;

transform noOrdering;

}

AMI2

{

type cyclicAMI;

inGroups 1 (cyclicAMI);

nFaces 40;

startFace 2460;

neighbourPatch AMI1;

transform noOrdering;

}

source patch

target patch

Appearing first in “boundary” file

55

Translate the pink-colored volume upward by 0.02m

56

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

Let’s recheck the weights!

𝑠𝑢𝑚(𝑤𝑒𝑖𝑔ℎ𝑡𝑠) =0.03

0.05= 0.6

0.05𝑚2 0.03𝑚2

Fraction of the intersecting areas

57

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

Let’s recheck the weights!

0.025𝑚2

0.005𝑚2

𝑤𝑒𝑖𝑔ℎ𝑡 =0.005

0.025= 0.2

58

User specified threshold for sum(weights)

Release note Version2.3.0

59

Thank You!

Kindly let me know if you have trouble downloading this slide.