project work: despcription of an adjoint method for object ...hani/kurser/os_cfd_2014/simon... ·...

34
CFD with OpenSource software A course at Chalmers University of Technology Taught by H˚ akan Nilsson Project work: Despcription of an adjoint method for object optimization related to wind noise Developed for OpenFOAM-2.3.x Author: Simon Lindberg Peer reviewed by: Matteo Nobile Jelena Andric Disclaimer: This is a student project work, done as part of a course where OpenFOAM and some other OpenSource software are introduced to the students. Any reader should be aware that it might not be free of errors. Still, it might be useful for someone who would like learn some details similar to the ones presented in the report and in the accompanying files. The material has gone through a review process. The role of the reviewer is to go through the tutorial and make sure that it works, that it is possible to follow, and to some extent correct the writing. The reviewer has no responsibility for the contents. February 2, 2015

Upload: others

Post on 22-May-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

CFD with OpenSource software

A course at Chalmers University of TechnologyTaught by Hakan Nilsson

Project work:

Despcription of an adjoint method forobject optimization related to wind noise

Developed for OpenFOAM-2.3.x

Author:Simon Lindberg

Peer reviewed by:Matteo NobileJelena Andric

Disclaimer: This is a student project work, done as part of a course where OpenFOAM and someother OpenSource software are introduced to the students. Any reader should be aware that it

might not be free of errors. Still, it might be useful for someone who would like learn some detailssimilar to the ones presented in the report and in the accompanying files. The material has gone

through a review process. The role of the reviewer is to go through the tutorial and make sure thatit works, that it is possible to follow, and to some extent correct the writing. The reviewer has no

responsibility for the contents.

February 2, 2015

Page 2: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

Contents

1 Theory 31.1 Aerodynamically induced wind noise . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Adjoint method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.2.1 The adjoint equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2.2 Specialization of equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 The solvers 72.1 adjointSensitivityFoam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.1.1 adjointShapeOptimizationFoam . . . . . . . . . . . . . . . . . . . . . . . . . 82.1.2 adjointSensitivityFoam.C . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.1.3 adjointOutletPressureFvPatchVectorField.C . . . . . . . . . . . . . . . . 112.1.4 adjointOutletVelocityFvPatchVectorField.C . . . . . . . . . . . . . . . . 122.1.5 createFields.H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.2 sensitivityMoveMesh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.2.1 createFields.H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

2.3 lighthillCostFunction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.3.1 createFields.H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3 Setting up a case 213.1 constant/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3.1.1 adjointBoxCase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.1.2 dynamicMeshDict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.1.3 transportProperties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.1.4 RASProperties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.2 0/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.3 system/ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.3.1 controlDict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.3.2 fvSolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

3.4 Running the case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

4 Results 27

5 Discussion 315.1 adjointSensitivityFoam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

5.1.1 laplacian(gamma,U) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.2 sensitivityMoveMesh problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

5.2.1 alpha value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.3 Frozen turbulence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

Bibliography 33

1

Page 3: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

CONTENTS CONTENTS

Introduction

The noise level in the car has been an increasing concern for the industry. While they successfullyhave been able to reduce the noise generated from the engine and the road, the aerodynamicallyinduced wind noise has gained attention of the engineers. In the spring of 2014, a master thesis wascarried out at Volvo Cars by Christian Sihvo [1]. The project was searching for a numerical methodusing an adjoint method to optimize the shape of an geometrical object. The method found workedon ”easy” geometrical object as boxes. The goal is to make this method work on more complex ge-ometries, such as back mirror which has a big influence on the aerodynamically induced noise in a car.

This project will describe the code written, and the theory behind the thesis work. The thesisused ANSA, a advanced commercial pre-processing tool for morphing, but this project will in-troduce a way of moving the points in the mesh using OpenFOAM. In this project, the originaladjointShapeOptimizationFoam solver in OpenFOAM will be modified to a new solver calledadjointSensitivityFoam.

2

Page 4: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

Chapter 1

Theory

This section will focus on the description of the adjoint method, and the theory regarding the windnoise.

1.1 Aerodynamically induced wind noise

In this project the Lighthill acoustic wave equation will be considered. This equation reads

∂2ρ

∂t2− a2∞∂2ρ

∂x2i

=∂2Tij∂xi∂xj

(1.1)

In the last term, Tij is called the Lighthill stress tensor

Tij = ρvivj + (p− a2∞)δij − τij . (1.2)

The first term of the Tij , the Reynold stress term, is the only term being considered in this project.The second term will be zero for flows without entropy fluctuations and the viscous term τij isconsidered to be zero for high Reynolds number flow. This only leads momentum flux term to besignificant, so that Tij ≈ ρvivj .[2]

The remaining right hand side of Eq. (1.1) can then, named J and be rewritten as

J =∂2

∂xi∂xj(ρvivj) = 2ρ

∆v +

3∑i=1,j=1i 6=j

∂vi∂vj∂xj∂xi

. (1.3)

Moreover J can be written as a sum of the domain part, with subscript Ω, and its boundary part,with subscript Γ, i.e.

J = JΩ + JΓ (1.4)

1.2 Adjoint method

The adjoint method of solving optimization problems in fluid dynamics is an optimization methodthat with only two solver calls, the primal and the adjoint respectively, can determine if a cell inthe mesh is favorable or unfavorable for the specific cost function. The method can be expressed asa minimization problem depending on our flow variables such as velocity v, pressure p, and designvariable α. The constraint in minimization problem is the incompressible, steady state Navier-Stokes

3

Page 5: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

1.2. ADJOINT METHOD CHAPTER 1. THEORY

equation. The problem can be written as

minimize J = J(v, p, α)

such that (v · ∇)v +∇p−∇ · (2νD(v)) = 0 (1.5)

∇ · v = 0

Where ν is the kinematic viscosity and the strain-rate tensor D(v) = 12 (∇v + (∇v)T ). A common

way of tackling a constrained optimization problem is introducing a Lagrange multipliers u and qas a Lagrangian relaxation to the optimization problem which then reads

minimize L := J +

∫Ω

(u, q)RdΩ (1.6)

where u is the adjoint velocity and q is the adjoint pressure. R is the constraints from Eq. (1.5), theincompressible RANS and continuity equation. Ω is the flow domain. Thus, in order to distinguishthe favourable cells, the sensitivity field of the design variable α has to be calculated by evaluatingthe total variance of L.

δL = δαL+ δvL+ δpL (1.7)

The Lagrange multipliers for the v and p can be choosen such that

δvL+ δpL = 0 (1.8)

Eqs. (1.7) and (1.8) together gives the expression for the sensitivity of the cell i

∂L

∂αi= ui · viVi (1.9)

where Vi is the volume of the cell i.

1.2.1 The adjoint equations

The adjoint velocity u, and the adjoint pressure q are not velocity and pressure in the physicalmeaning, but have the same dimensions, which suggests that they can be treated similarily. UsingEqs. (1.6) and (1.8) we acquire

δvJ +

∫Ω

(u, q)δvRdΩ + δpJ +

∫Ω

(u, q)δpRdΩ = 0 (1.10)

Here R stands for the incompressible Navier Stokes equations from Eq. (1.5). The change ofeddy viscosity will be neglected due to an approximation called ”frozen turblence”, and this is onlycorrect for laminar flow. This will be an error source for this calculation, but it is a commonly usedapproximation. With some further derivation notm shown here the Eq. (1.10) now reads

δvJ + δpJ +

∫Ω

u · ((δv · ∇)v + (v · ∇)δv −∇ · (2νD(δv)))dΩ−

−∫Ω

q∇ · δvdΩ +

∫Ω

u · ∇δpdΩ = 0 (1.11)

4

Page 6: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

1.2. ADJOINT METHOD CHAPTER 1. THEORY

After splitting the cost function J into the boundary Γ and domain Ω part and doing some partialintegration we get the equation

0 =

∫Γ

(u · v +∂JΓ

∂p)δpdΓ +

∫Ω

(−∇ · u +∂JΩ

∂p)δpdΩ+

+

∫Γ

(n(u · v) + u(v · n) + 2νn ·D(n +∂JΓ

∂v)) · δvdΓ−

−∫Γ

2νn ·D(δv) · udΓ+

+

∫Ω

(−∇u · v − (v·)u−∇ · (2νD(u) +∇q +∂JΩ

∂v)) · δvdΩ (1.12)

To fulfill this equation for any δv and δp each integrand has to be 0 individually. The integrandsover the domain gives the adjoint system of equations which are quite similar to the primal one

−2D(u)v = −∇q +∇ · (2νD(u))− ∂JΩ

∂v(1.13)

∇ · u =∂JΩ

∂p(1.14)

Where −2D(u)v = −∇u · v − (v · ∇)u From the eq. 1.12 we can also see the boundary equations∫Γ

(n(u · v) + u(v · n) + 2νn ·D(u− qn +

∂JΓ

∂v

)δvdΓ−

−∫Γ

2νn ·D(δv) · udΓ = 0 (1.15)

∫Γ

(u · v +

∂JΓ

∂p

)δpdΓ = 0 (1.16)

It can be seen in Eqs. (1.13) and (1.14) that if the cost function only has only the contributionfrom the boundaries, the solver will be the same for all different cost functions as the last term ofEq. (1.13) will be zero and the whole RHS of Eq. (1.14) will be zero. If the cost function havecontributions from the domain then the last term of the two equations might not be zero and haveto be implemented in the solver. In this project the cost function do have a contribution from thedomain and the sovler must thus be changed to accoommodate this.

1.2.2 Specialization of equations

This flow is ducted, it is inside a domain with inlet, outlet and walls and the equation has tobe specialized for this flow, as well as for our cost function. This report will not go through thederivation of the boundary conditions, as it is not the main focus of the project. The conditions willonly be valid for a specific primal boundary conditions though, and the ones used in this projectwill be listed in 1.1.

Wall Inlet Outletv No-slip Prescribed value Zero gradientp Zero gradient Zero gradient p = 0

Table 1.1: Boundary conditions for the primals

The adjoint boundary conditions will then be as follows

5

Page 7: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

1.2. ADJOINT METHOD CHAPTER 1. THEORY

Wall and inlet boundary conditions

ut = 0 (1.17)

un = −∂JΩ

∂p(1.18)

n · ∇q = 0 (1.19)

Where the subscript t stands for the tangential direction and subscript n stands for the normaldirection.

Outlet boundary conditions

q = u · v + unvn + ν(n · ∇)un +∂JΓ

∂vn(1.20)

0 = vnut + ν(n · ∇)ut +∂JΓ

∂vt(1.21)

The cost function

As it can be seen these equations have plenty of input from the cost function, so different derivationsof the cost function has to be derived. For this cost function, the Lighthill stress tensor

J =∂2

∂xi∂xj(ρvivj) (1.22)

it is easy to see that all derivation with the pressure will be zero, and that the noise level will onlybe important in the domain for this cost function. That leads us with

∂JΩ

∂p= 0 (1.23)

∂JΓ

∂v= 0 (1.24)

∂JΓ

∂p= 0 (1.25)

Then it only remains to calculate the term from the Eq. (1.13)

∂JΩ

∂v=

∫Ω

∂3

∂xi∂xj∂vi(ρvivj)dΩ =

∫Ω

∂2

∂xi∂xj(ρvj)dΩ =

=

∫Ω

ρ∇ · (∇v)dΩ =

∫Ω

ρ∆vdΩ (1.26)

For more information about the method, and how to aquire the equations please see Ulf Nilsson’swork in the course ”CFD with OpenSource software” 2013 [3], and C. Othmers article [4], as wellas Christan Sihvo’s thesis [1] for this specific cost function.

6

Page 8: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

Chapter 2

The solvers

This chapter contains the description and the modification of the solvers. In Fig. 2.1 it is possible tofollow how the programs are intended to be run. Both simpleFoam and adjointSensitivityFoam

use the SIMPLE-type algoritm for the pressure-velocity coupling.

Create a blockMesh

run simpleFoam for v and p

run lighthillCostFunction

to see the valueof the wind noise

run adjointSensitivityFoam

for u and q andthe sensitivity field

run sensitivityMoveMesh

to update the geom-etry of the object

next iterationIs this sat-isfactory?

stop

no

yes

Figure 2.1: Flowchart of the way to use the program described in this project

7

Page 9: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.1. ADJOINTSENSITIVITYFOAM CHAPTER 2. THE SOLVERS

2.1 adjointSensitivityFoam

As a starting point for the solver we will use adjointShapeOptimizationFoam and do make sub-stansional changes to the program. It is still the best starting point among the OpenFoam solversdue to the fact that it calculates adjoint velocity and adjoint pressure. This part is a description ofwhat was done in the master thesis at Volvo by C. Sihvo. [1]

2.1.1 adjointShapeOptimizationFoam

adjointShapeOptimizationFoam/

adjointContinuityErrs.H

adjointOutletPressure/

adjointOutletPressureFvPatchScalarField.C

adjointOutletPressureFvPatchScalarField.H

adjointOutletVelocity/

adjointOutletVelocityFvPatchVectorField.C

adjointOutletVelocityFvPatchVectorField.H

adjointShapeOptimizationFoam.C

createFields.H

createPhia.H

initAdjointContinuityErrs.H

Make/

options

files

Figure 2.2: Directory structure for adjointShapeOptimizationFoam.

The adjointShapeOptimizationFoam solver applies a ”one-shot” approach to solve the primal andadjoint solvers and the fields are only partially converged. In this project the goal is to solve thefields more carefully and to converge both the primal and adjoint variable before changing the ge-ometry. Thus the primal variables will be solved with simpleFoam before calculating the adjointfields and the sensitivities with adjointSensitivityFoam.

The starting point of the process of creating the adjointSensitivityFoam is to copy the origi-nal solver to the user directory, as follows:

cd $WM PROJECT DIR

cp -r --parents applications/solvers/incompressible/adjointShapeOptimizationFoam \$WM PROJECT USER DIR

Rename the solver to name of choice, e.g. adjointSensitivityFoam

cd $WM PROJECT USER DIR/applications/solvers/incompressible/

mv adjointShapeOptimizationFoam adjointSensitivityFoam

cd adjointSensitivityFoam

mv adjointShapeOptimizationFoam.C adjointSensitivityFoam.C

Rename the executable and change the location in Make/files:

sed -i s/FOAM APPBIN/FOAM USER APPBIN/g Make/files

sed -i s/adjointShapeOptimizationFoam/adjointSensitivityFoam/g Make/files

Clean the previous compilation and recompile with the command wclean and wmake respectively.

8

Page 10: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.1. ADJOINTSENSITIVITYFOAM CHAPTER 2. THE SOLVERS

The rest of this section will be a combination of explaination of the code as well as what is neededto add or remove to create the adjointSensitivityFoam solver.

2.1.2 adjointSensitivityFoam.C

83 Info << "\nStarting time loop\n" << endl;848586 while (simple.loop ())87 88 Info << "Time = " << runTime.timeName () << nl << endl;8990 laminarTransport.lookup("lambda") >> lambda;9192 // alpha +=93 // mesh.relaxationFactor ("alpha ")94 // *( lambda*max(Ua & U, zeroSensitivity) - alpha );95 alpha +=96 mesh.fieldRelaxationFactor("alpha")97 *(min(max(alpha + lambda *(Ua & U), zeroAlpha), alphaMax) - alpha );9899 zeroCells(alpha , inletCells );

100 // zeroCells(alpha , outletCells );101102 // Pressure -velocity SIMPLE corrector103 104 // Momentum predictor105106 tmp <fvVectorMatrix > UEqn107 (108 fvm::div(phi , U)109 + turbulence ->divDevReff(U)110 + fvm::Sp(alpha , U)111 );112113 UEqn (). relax ();114115 solve(UEqn() == -fvc::grad(p));116117 p.boundaryField (). updateCoeffs ();118 volScalarField rAU (1.0/ UEqn ().A());119 U = rAU*UEqn ().H();120 UEqn.clear ();121 phi = fvc:: interpolate(U) & mesh.Sf();122 adjustPhi(phi , U, p);123124 // Non -orthogonal pressure corrector loop125 while (simple.correctNonOrthogonal ())126 127 fvScalarMatrix pEqn128 (129 fvm:: laplacian(rAU , p) == fvc::div(phi)130 );131132 pEqn.setReference(pRefCell , pRefValue );133 pEqn.solve ();134135 if (simple.finalNonOrthogonalIter ())136 137 phi -= pEqn.flux ();138 139 140141 #include "continuityErrs.H"142143 // Explicitly relax pressure for momentum corrector144 p.relax ();145

9

Page 11: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.1. ADJOINTSENSITIVITYFOAM CHAPTER 2. THE SOLVERS

146 // Momentum corrector147 U -= rAU*fvc::grad(p);148 U.correctBoundaryConditions ();149

Listing 2.1: file adjointShapeOptimizationFoam.C

In listing 2.1 we see that we need to remove lines 90 - 149 to remove the parts regarding the porosityand the primal solver in adjointSensitivityFoam.C. We will also need to remove the line in listing2.2 in the adjointSensitivityFoam.C as we no longer have any continuity error for the primal tocalculate.

76 #include "initContinuityErrs.H"

Listing 2.2: file adjointShapeOptimizationFoam.C

We then must account for the ∂Ω∂v term in the adjoint equation, and add this term, as well as remove

the porosity part of the equation.

169 tmp <fvVectorMatrix > UaEqn170 (171 fvm::div(-phi , Ua)172 - adjointTransposeConvection173 + turbulence ->divDevReff(Ua)174 + fvm::Sp(alpha , Ua)175 );176177 UaEqn (). relax ();178179 solve(UaEqn() == -fvc::grad(pa));

Listing 2.3: file adjointShapeOptimizationFoam.C before change

169 tmp <fvVectorMatrix > UaEqn170 (171 fvm::div(-phi , Ua)172 - adjointTransposeConvection173 + turbulence ->divDevReff(Ua)174 );175176 UaEqn (). relax ();177178 solve(UaEqn() == -fvc::grad(pa) - fvc:: laplacian(gamma ,U));

Listing 2.4: file adjointShapeOptimizationFoam.C after change

As seen on line 178 in listing 2.4 we introduce the laplacian from Eq. (1.26). The interesting hereis that the ρ in the equation has dissapeared and become a gamma. The gamma has the dimensionsof m2/s and is a constant added to make sure that the dimensions are correct. This constant hasbeen renamed in this project from the work done at Volvo, where it was called nu.

As stated in chapter 1.2 the equations for the adjoint variables are solved with ”frozen turbulence”as an approximation, which means that the following line in listing 2.5 can be removed since theνeff is already calculated when simpleFoam was run.

215 turbulence ->correct ();

Listing 2.5: part of file adjointShapeOptimizationFoam.C to delete

The only thing left to do is to add a part that calculates the sensitivity field for the object. The codeis added before the line with the member functions runTime.write() (the line numbering is used tomake it easier to refer to certain parts of the code).

1 word patchName = "innerBox";2 label patchID = mesh.boundaryMesh (). findPatchID(patchName );3 error err("Error!\n");

10

Page 12: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.1. ADJOINTSENSITIVITYFOAM CHAPTER 2. THE SOLVERS

4 if(-1 == patchID)5 err.exit ();6 const fvPatch& cPatch = mesh.boundary ()[ patchID ];7 const labelUList& cellsPatch = cPatch.faceCells ();8 forAll(cellsPatch ,cellI)9 sens[cellsPatch[cellI ]] = (Ua[cellsPatch[cellI ]] & U[cellsPatch[cellI ]]) * \

10 mesh.V()[ cellsPatch[cellI ]];11 forAll(cPatch ,faceI)12 13 label faceCellI = cPatch.faceCells ()[ faceI];14 sens.boundaryField ()[ patchID ][faceI] = sens[faceCellI ];15 1617 // scalar maxSens(Foam::sqrt(gMaxMagSqr(sens )));18 scalar maxSens(gMax(sens ));19 scalar minSens(gMin(sens ));20 maxSens = (maxSens*maxSens >= minSens*minSens ? fabs(maxSens) : \21 fabs(minSens ));22 sens = sens/( maxSens+SMALL );

Listing 2.6: file adjointSensitivityFoam.C

As can be seen in listing 2.6 at line 1 we are referring to the boundary called ”innerbox”, which isthe box we want to investigate. After finding the patchID and making sure that the patch exists,some necessary constants are created in lines 6 and 7. The sensitivity is then calculated on the loopon line 9 (which is shown on two lines here for space issues). On the next loop on line 11-15 wemake sure that the the boundary of our object have the same value as the cell have. Since the sen-sitivity is v ·uVi it can’t be calculated on the boundary due to the no slip condition on the boundary.

To make it easier to view the sensitivity later it is then scaled on lines 18-22 with the maximumvalue of the magnitude of either the most positive, or most negative value.

2.1.3 adjointOutletPressureFvPatchVectorField.C

The function for the adjoint outlet pressure will be derived from Eq. (1.20). The first differencefrom the original implementation is that this equation needs of turbulent viscosity, νeff . The line#include "RASModel.H" has to be added in the beginning of the file, so that the viscosity can beacquired from the RASProperies.

107 operator ==(( phiap/patch (). magSf () - 1.0)* phip/patch (). magSf() + (Up & Uap));

Listing 2.7: part of adjointOutletPressureFvPatchScalarField.C to remove

The normal components of the velocities are needed, and are constructed using the fluxes and theface area as

vpatch,n =

(Φp ·AA2

)· n (2.1)

upatch,n =

(Φa ·AA2

)· n (2.2)

The new operator we need to add is derived from Eq. (1.20)

q = u · v + unvn + ν(n · ∇)un, (2.3)

with the approximation that ν(n · ∇)un ≈ νupatch,n−uneigh,n

∆ , where ∆ is the distance between thenodes.

scalarField Up_n = (phip*patch ().Sf()/sqr(patch (). magSf ())) & patch ().nf();// Normal component of the adjoint velocityscalarField Uap_n = (phiap*patch ().Sf()/sqr(patch (). magSf ())) & patch ().nf();

const incompressible :: RASModel& rasModel =

11

Page 13: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.1. ADJOINTSENSITIVITYFOAM CHAPTER 2. THE SOLVERS

db(). lookupObject <incompressible ::RASModel >("RASProperties");

scalarField nueff = rasModel.nuEff ()(). boundaryField ()[ patch (). index ()];

// inverse of the distance between nodesconst scalarField& deltainv = patch (). deltaCoeffs ();

// Magnitude of the normal component of the neighboring nodescalarField Uaneigh_n = (Uap.patchInternalField () & patch ().nf());

operator ==(( Uap & Up) + (Up_n*Uap_n) + nueff*(Uap_n -Uaneigh_n )* deltainv );

Listing 2.8: code in adjointOutletPressureFvPatchScalarField.C to add

2.1.4 adjointOutletVelocityFvPatchVectorField.C

Special outlet boundary conditions have to be set, and these will be derived from Eq. (1.21). As inthe outlet pressure conditions is the νeff used. The line #include "RASModel.H" must be added

in the beginning of the fileA·

const fvsPatchField <scalar >& phiap =patch (). lookupPatchField <surfaceScalarField , scalar >("phia");

const fvPatchField <vector >& Up =patch (). lookupPatchField <volVectorField , vector >("U");

scalarField Un(mag(patch ().nf() & Up));vectorField UtHat ((Up - patch ().nf()*Un)/(Un + SMALL ));

vectorField Uan(patch ().nf()*( patch ().nf() & patchInternalField ()));

vectorField :: operator =(phiap*patch ().Sf()/sqr(patch (). magSf ()) + UtHat );// vectorField :: operator =(Uan + UtHat );

Listing 2.9: code in adjointOutletVelocityFvPatchScalarField.C to remove

In the implementation done by C. Sihvo [1] it seems that the following approximation was done

ν(n · ∇)ut ≈ νup,n − uneigh,n

∆, (2.4)

which does not seem intuitive that the tangential part of the velocity will become the normal [1].The following derivation is done with a different approach, in which the Eq. (2.4) should be writtenas follows

ν(n · ∇)ut ≈ νup,t − uneigh,t

∆. (2.5)

Using Eqs. (2.5) and (1.21) ut is calculated. The p,t stands for the tangential part at the patch.Patch is any type of boundary in OpenFoam, and the node at the patch will be the node at theboundary. The neigh,t is the tangential part at the neighbouring node. This approximation from Eq.(2.5) is the same as was used by Ulf Nilssons [3]. In the following derivation ut = up,t.

0 = vnut + ν(n · ∇)ut

0 = vnut + νup,t − uneigh,t

up,t +ν

vn

up,t∆

vn

uneigh,t∆

up,t =ν

vn

uneigh,t∆

1(1 + ν

∆vn

) =νuneigh,tvn∆ + ν

(2.6)

12

Page 14: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.1. ADJOINTSENSITIVITYFOAM CHAPTER 2. THE SOLVERS

const fvsPatchField <scalar >& phip =patch (). lookupPatchField <surfaceScalarField , scalar >("phi");

// const fvsPatchField <scalar >& phiap =// patch (). lookupPatchField <surfaceScalarField , scalar >(" phia ");

const fvPatchField <vector >& Uap =patch (). lookupPatchField <volVectorField , vector >("Ua");

const incompressible :: RASModel& rasModel =db(). lookupObject <incompressible ::RASModel >("RASProperties");

scalarField nueff = rasModel.nuEff ()(). boundaryField ()[ patch (). index ()];

const scalarField& deltainv = patch (). deltaCoeffs ();

// Primal magnitude of velocityscalarField Up_ns = phip/patch (). magSf ();

// Neighbouring cell vel.vectorField Uaneigh = Uap.patchInternalField ();vectorField Uaneigh_n = (Uaneigh & patch ().nf())* patch ().nf(); // NormalvectorField Uaneigh_t = Uaneigh - Uaneigh_n;

// vectorField Uan_p = phiap*patch ().Sf()/ sqr(patch (). magSf ()) ;vectorField Uan_p = Uap & patch ().nf() * patch ().nf();vectorField Uap_t = (nueff * Uaneigh_t) / (Up_ns / deltainv + nueff );

operator ==( Uap_t + Uan_p );

Listing 2.10: code in adjointOutletVelocityFvPatchScalarField.C to add

Most of the added code is to create the needed vector fields, and the line vectorField Uap t

corresponds to Eq. (2.6).

2.1.5 createFields.H

The createFields.H for the adjoint solver must read the fields for U ,Ua,p,pa. It must also includethe files for the fluxes #include "createPhi.H" and #include "createPhia.H". The changesdone to the file is to remove all lines regarding to the alpha field as well as adding two new scalars,nu and gamma and the sensitivity field as shown in 2.11.

dimensionedScalar nu(laminarTransport.lookup("nu"));dimensionedScalar gamma(laminarTransport.lookup("gamma"));

const labelList& inletCells = mesh.boundary ()["inlet"]. faceCells ();

volScalarField sens(

IOobject(

"sensitivity",runTime.timeName(),mesh ,IOobject :: READ_IF_PRESENT ,IOobject :: AUTO_WRITE

),(Ua&U)*0.0

);

Listing 2.11: The sensitivity field as well as the laminarTrasport.lookup

13

Page 15: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.2. SENSITIVITYMOVEMESH CHAPTER 2. THE SOLVERS

2.2 sensitivityMoveMesh

sensitivityMoveMesh/

sensitivityMoveMesh.C

createFields.H

Make/

options

files

Figure 2.3: Directory structure for sensitivityMoveMesh.

As a starting point for this solver, we will use the moveMesh solver in the OpenFoam library andupgrade it as discussed in the ”Moving boundary problem based on calculated data”-discussion onCFD-online forum [5]. Some changes are done to adapt the solver for this case, but the basic func-tionality is the same.

The procedure is the same as for the adjointSensitivityFoam solver, to copy the original solverto the user directory, as follows:

cd $WM PROJECT DIR

cp -r --parents applications/utilities/mesh/manipulation/moveMesh \$WM PROJECT USER DIR

Rename it is not mixed up with the original solver, here to sensitivityMoveMesh

cd $WM PROJECT USER DIR/utilities/mesh/manipulation/

mv moveMesh sensitivityMoveMesh

cd sensitivityMoveMesh

mv moveMesh.C sensitivityMoveMesh.C

Rename the executable and change the location in Make/files:

sed -i s/FOAM APPBIN/FOAM USER APPBIN/g Make/files

sed -i s/moveMesh/sensitivityMoveMesh/g Make/files

Clean the previous compilation and recompile with the command wclean and wmake respecitvely.

The original solver is quite simple and reads the 0/pointDisplacement or 0/pointMotionU files,depending on which solver is chosen in constant/dynamicMeshDict to move the mesh. What willbe done is to add some functionalities to calculate a new pointDisplacement from data acquiredduring the simulations to create the moving part. We must first add a few include files

29 #include "argList.H"30 #include "fvCFD.H"31 #include "simpleControl.H"32 #include "Time.H"33 #include "fvMesh.H"34 #include "motionSolver.H"35 #include "velocityMotionSolver.H"36 #include "primitivePatchInterpolation.H"

Listing 2.12: include section of sensitivityMoveMesh.C

As it can see in listing 2.13 after the int main(int argc, char *argv[]) line the part patch thatha to be moved has to be defined. In this project the patch is called ”innerBox”. Then the basisfiles for the displacement is defined which is pointDisplacement.

autoPtr <motionSolver > motionPtr = motionSolver ::New(mesh);

14

Page 16: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.2. SENSITIVITYMOVEMESH CHAPTER 2. THE SOLVERS

word patchName = "innerBox";label patchID = mesh.boundaryMesh (). findPatchID(patchName );

pointVectorField& PointDisplacement = const_cast <pointVectorField&>(

mesh.objectRegistry :: lookupObject <pointVectorField >(

"pointDisplacement")

);

Listing 2.13: first section of sensitivityMoveMesh.C after int main..

After the ”pointDisplacement” is acquired the vectorField with the values of the displacement forthe specific patch must be gathered, as done in listing 2.14

//Get the vector field of the patchvectorField &pDisp=refCast <vectorField >( PointDisplacement.boundaryField ()[ patchID ]);

//Find the relevant size of the vector and declare a vectorField.int Psize= pDisp.size ();vectorField dispVals(Psize );

Listing 2.14: creation of the vectorField dispVals in sensitivityMoveMesh.C

In listing 2.15 the code first set up the interpolater using the primitivePatchInterpolation.H classand are then interpolates the selected field to smoothen the motion. The field in this project is thesensitivity field. The last two lines creates a vector field with the old values of the pointdisplacement,and is then creating the normalvector called PointNormalVector.

//- set -up interpolatorprimitivePatchInterpolation patchInterpolator( mesh.boundaryMesh ()[ patchID] );

// displacement based on the external calculation (must provide field data in 0/)scalarField sensitivityPatch = sensitivity.boundaryField ()[ patchID ];

//- perform interpolationscalarField faceValues = \patchInterpolator.faceToPointInterpolate(sensitivityPatch );

vectorField &PointPointer = \refCast <vectorField >( PointDisplacement.boundaryField ()[ patchID ]);

vectorField PointNormalVector = \mesh.boundaryMesh ()[ patchID ]. pointNormals ();

Listing 2.15: interpolation of the sensitivity field in sensitivityMoveMesh.C

After the vectorFields in listing 2.15 the new values to the dispVals can be calculated, as in listing2.16, where the calculation is done for x,y,z direction respectively. The old value of the displacementis the PointPointer[index].x(), and then the new part alpha.value() * faceValues[index]

* PointNormalVector[index].x(); is added. alpha.value() is a dimensionless constant usedto reduce the movement of the boundary. The sensitivity is up the value 1, which is a very largemovement for the mesh. The alpha.value() must reduce the movement with the regards to themesh that is used. It is defined in constant/transportProperties.

// loop over points to move the nodesforAll(dispVals , index)

dispVals[index ].x() = PointPointer[index ].x() - \alpha.value() * faceValues[index] * PointNormalVector[index].x();

dispVals[index ].y() = PointPointer[index ].y() - \alpha.value() * faceValues[index] * PointNormalVector[index].y();

dispVals[index ].z() = PointPointer[index ].z() - \

15

Page 17: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.2. SENSITIVITYMOVEMESH CHAPTER 2. THE SOLVERS

alpha.value() * faceValues[index] * PointNormalVector[index].z();

Listing 2.16: creating of the new dispVals values in sensitivityMoveMesh.C

The last thing to do before the moveMesh loop is to assign the dispVals to the PointDisplacement.boundaryField()

as done in listning 2.17

//Once the values have been assigned to dispVals ,// assign them to cellDisplacement boundaryFieldPointDisplacement.boundaryField ()[ patchID] == dispVals;

Listing 2.17: defining a new pointDisplacement field in sensitivityMoveMesh.C

The final lines of the sensitivityMoveMesh.C are shown in listing 2.18. This is part of the originalmoveMesh.C code and is not changed for this project.

while (runTime.loop ())

Info << "Time = " << runTime.timeName () << endl;

mesh.movePoints(motionPtr ->newPoints ());

runTime.write ();

Info << "ExecutionTime = " << runTime.elapsedCpuTime () << " s"<< " ClockTime = " << runTime.elapsedClockTime () << " s"<< nl << endl;

Info << "End\n" << endl;

return 0;

Listing 2.18: while loop in sensitivityMoveMesh.C

2.2.1 createFields.H

The fields that the sensitivityMoveMesh needs are the sensitivity and the constant alpha. Thesolver will also need to read the mesh. This can be seen in listing 2.19. This file does not exist inthe original moveMesh utility and need so be created.

1 Info << "Reading field sensitivity\n" << endl;23 volScalarField sensitivity4 (5 IOobject6 (7 "sensitivity",8 runTime.timeName(),9 mesh ,

10 IOobject :: MUST_READ_IF_MODIFIED ,11 IOobject :: NO_WRITE12 ),13 mesh14 );1516 Info << "Reading transportProperties\n" << endl;1718 IOdictionary transportProperties19 (20 IOobject21 (22 "transportProperties",23 runTime.constant(),24 mesh ,25 IOobject :: MUST_READ_IF_MODIFIED ,

16

Page 18: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.2. SENSITIVITYMOVEMESH CHAPTER 2. THE SOLVERS

26 IOobject :: NO_WRITE27 )28 );293031 Info << "Reading coefficient Alpha\n" << endl;3233 dimensionedScalar alpha34 (35 transportProperties.lookup("alpha")36 );

Listing 2.19: createFields.H

When all files are created and rewritten the program needs to be compiled by typing wmake.

17

Page 19: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.3. LIGHTHILLCOSTFUNCTION CHAPTER 2. THE SOLVERS

2.3 lighthillCostFunction

lighthillCostFunction/

lighthillCostFunction.C

createFields.H

Make/

options

files

Figure 2.4: Directory structure for lighthillCostFunction.

This is the code that is not based on any original OpenFOAM-code. To create the correct environ-ment write

cd $WM PROJECT USER DIR

mkdir -p applications/utilities/lighthillCostFunction

cd applications/utilities/lighthillCostFunction

foamNewSource App lighthillCostFunction

tree

This will create an empty template of the form of Fig. 2.4 and the rest of the code can be added asfollows. The createFields.H is not created but can be created by typing touch createFields.H.It is important to change the Make/files file and add change the destination as follows.

sed -i s/FOAM APPBIN/FOAM USER APPBIN/g Make/files

In the listings 2.20 - 2.23 the code for the cost function is listed. The line numbering is shownto refer to a specific line of the code.

1 #include "fvCFD.H"2 #include "cellSet.H"34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //56 int main(int argc , char *argv [])7 8 #include "setRootCase.H"9 #include "createTime.H"

10 #include "createMesh.H"11 #include "createFields.H"1213 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

Listing 2.20: The lighthillCostFunction.C

In listing 2.20 the include files and initialization is listed. The only interesting class here is the#include "cellSet.H" line, which enables to select a group of cells based on their geometric locationin the mesh for measuring. To be able to use the cellSet.H the lines-I$(LIB SRC)/meshTools/lnInclude) and -lmeshTools the Make/options.

14 Info << "Compute the tensor: velocity gradient grad(U)!\n" << endl;15 volTensorField gradU(fvc::grad(U));16 Info << "Compute the vector: divergence ofvelocity gradient div(grad(U))!\n" \17 << endl;18 volVectorField divGradU(fvc::div(gradU ));1920 volScalarField Tij(21 IOobject22 (23 "Tij",24 runTime.timeName(),

18

Page 20: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.3. LIGHTHILLCOSTFUNCTION CHAPTER 2. THE SOLVERS

25 mesh ,26 IOobject ::NO_READ ,27 IOobject :: AUTO_WRITE28 ),29 (mesh.C() & mesh.C())*0.030 );

Listing 2.21: The lighthillCostFunction.C

In the second part of the code shown in listing 2.21 it is shown how initial gradU and divGradU arecalculated, and the volScalarField is created.

31 scalar volume = 0.0;32 cellSet cSet(mesh ,"box");33 const labelList& cells = cSet.toc();34 forAll(cells ,cellI)35 36 Tij[cells[cellI]] =37 2*( divGradU[cells[cellI]] & U[cells[cellI ]]) + \38 sqr(gradU[cells[cellI ]]. component(tensor ::XX)) + \39 sqr(gradU[cells[cellI ]]. component(tensor ::YY)) + \40 sqr(gradU[cells[cellI ]]. component(tensor ::ZZ)) + \41 2*( gradU[cells[cellI ]]. component(tensor ::YX) * \42 gradU[cells[cellI ]]. component(tensor ::XY) + \43 gradU[cells[cellI ]]. component(tensor ::ZY) * \44 gradU[cells[cellI ]]. component(tensor ::YZ) + \45 gradU[cells[cellI ]]. component(tensor ::XZ) *\46 gradU[cells[cellI ]]. component(tensor ::ZX));47 volume += mesh.V()[ cells[cellI ]];48

Listing 2.22: The lighthillCostFunction.C

In the third listing 2.22 the real calculation of the value of the stress tensor in each cell is shownat lines 36-46. The equation evaluated is Eq. (1.3) with the omittance of the ρ constant. At line32 we see the call for the file box, which is in the polyMesh/sets directory. It must be createdbefore running the lighthillCostFunction program. The file used to create it is listed in listing2.24. The line 47 is calculating the accumulated volume of the cells that is used to evaluate the costfunction. At line 31 the volume is initialized.

49 Tij.write ();5051 Info << "Number of cells in box: " << cSet.size() << endl;5253 Info << "Integrate Tij in the whole volume !\n" << endl;54 scalar intTij = gSum(Tij.internalField () * mesh.V());55 reduce(volume ,sumOp <scalar >());5657 Info << "The cost function has the value of: " << intTij /( volume+SMALL) << " \58 [1/s2]\ nDone!\n" << endl;5960 return 0;61

Listing 2.23: The lighthillCostFunction.C

The last part of the lighthillCostFunction.C file is shown in listing 2.23, which is the part wherethe program writes the tensors, and sums it all together before showing the user what the value ofthe cost function is.

cellSet box new boxToCell (-0.15 -0.015 0) (0.035 0.035 0.03)quit

Listing 2.24: The batchSetSet file

The listing 2.24 is showing a file that is used for creating the box file with all the cells used inlighthillCostFunction.C. It creates a box with the coordinates listed. The coordinates are the

19

Page 21: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

2.3. LIGHTHILLCOSTFUNCTION CHAPTER 2. THE SOLVERS

opposite vertices of the box and therfore the whole volume can be calculated using only those points.The files is called by typing in the terminal

setSet -batch system/batchSetSet

if the batchSetSet file is in the system directory. The file does not have to be named batchSetSet,it can be called anything.

2.3.1 createFields.H

The only field that the lighthillCostFunction is needing is the velocity field, so the createFields.Hfile will only need to read that field seen in the listing 2.25

1 Info << "Reading field U\n" << endl;2 volVectorField U3 (4 IOobject5 (6 "U",7 runTime.timeName(),8 mesh ,9 IOobject ::MUST_READ ,

10 IOobject :: AUTO_WRITE11 ),12 mesh13 );

Listing 2.25: createFields.H file

When all files are written, complile the code using wmake.

20

Page 22: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

Chapter 3

Setting up a case

This chapter will go through the settings needed to run the boxWindCase case that can be downloadedfrom the course homepage. In the Fig. 3.1 all the directories and files that the case contains aredisplayed. The case is a box in a ducted flow, where the geometry of the box will be changed toreduce the aerodynamically induced wind noise. The flow is 1ms over the box.

boxWindCase/

0/

epsilon

k

nut

p

pa

U

Ua

pointDisplacement

constants/

polyMesh/

blockMeshDict

dynamicMeshDict

RASProperties

transportProperties

turbulenceProperties

system/

batchSetSet

controlDict

decomposeParDict

fvSchemes

fvSolution

Figure 3.1: Directory structure for boxWindCase.

3.1 constant/

In this section the files in the constant/ directory will be explained.

21

Page 23: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

3.1. CONSTANT/ CHAPTER 3. SETTING UP A CASE

3.1.1 adjointBoxCase

The mesh used for this case is from a blockMeshDict that utilizes a symmetryPlane for reducing thecomputational time. The mesh is rather coarse to reduce computational time. It is thus possiblethat the coarse mesh will reduce the accuracy of the solution. The mesh consits of 30660 hexahedracells, and the patches are

• inlet

• outlet

• slip

• plate

• innerBox

• sym

Here slip is the wall opposite the symmetry wall which is the wall with the box cut in half. InnerBoxis the box that is the subject of the movements and plate is the floor and the roof of the domain.

Figure 3.2: The mesh used without the inlet.

3.1.2 dynamicMeshDict

dynamicFvMesh dynamicMotionSolverFvMesh;

motionSolverLibs ( "libfvMotionSolvers.so" );

/*solver velocityLaplacian;velocityLaplacianCoeffs

diffusivity directional ( 0 100 0 );

22

Page 24: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

3.2. 0/ CHAPTER 3. SETTING UP A CASE

// diffusivity uniform;*/

solver displacementLaplacian;displacementLaplacianCoeffs

diffusivity quadratic inversePointDistance (innerBox );

Listing 3.1: dynamicMeshDict

In listing 3.1 it is stated what kind of displacement solver is used for the mesh movement. ThevelocityLaplacian is commented and it is the displacementLaplacian that is used and the diffusivityis specified on the innerBox.

3.1.3 transportProperties

In the listing 3.2 the three important constats used is listed

transportModel Newtonian;

nu nu [0 2 -1 0 0 0 0] 1e-5;gamma gamma [0 2 -1 0 0 0 0] 5e-6;alpha alpha [0 0 0 0 0 0 0] 0.00006;

Listing 3.2: The transportProperties

The value of gamma was set to be 1 · 10−5 in the project at Volvo. In this project both 1 · 10−5 and5 · 10−5 will be tested. This is done to see if the result can be improved by changing this entity, orif it should be interpreted as the viscosity.

The ν value is used for the turbulence, and the α value is a dimensionless constant for scalingthe sensitivity in the sensitivityMoveMesh. The value 0.00006 means that a sensitivity will bemultiplied with the constant to get the movement in meter.

3.1.4 RASProperties

RASModel kEpsilon;

turbulence on;

printCoeffs on;

Listing 3.3: The RASProperties

The file RASProperties is showing only that kEpsilon model is used and that the turbulence is on.

3.2 0/

In the 0/ directory, the initial and boundary conditions for the different fields are located. Theintial values for the k and epsilon files have to be determined. The initial k value was set to 0.375,and the intial epsilon value was set to 14.763. For all the initial condition files, the symmetryPlanecondition can be used for the sym patch, as well as the slip condition for the slip patch.

boundaryField

inlet

type fixedValue;value uniform (0 0 0);

23

Page 25: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

3.3. SYSTEM/ CHAPTER 3. SETTING UP A CASE

outlet

type adjointOutletVelocity;value uniform (0 0 0);

innerBox

type fixedValue;value uniform (0 0 0);

Listing 3.4: The 0/Ua file

The listing 3.4 shows some of the initial conditions for the adjoint velocity where the adjointOutletVelocityconditions is very important.

boundaryField

inlet

type zeroGradient;

outlet

type adjointOutletPressure;value uniform 0;

innerBox

type zeroGradient;

Listing 3.5: The 0/pa file

The listing 3.5 shows that the outlet conditions for the adjoint pressure must be described as well.

3.3 system/

In this section, the different files in the system/ directory will be explained.

3.3.1 controlDict

In the controlDict the number of iterations, and how often results has to be written are defined.This must be changed before any solver is run. The first time the simpleFoam is used the endTime

can be set at 3000, and later it is often enough to iterate 2000 steps. The adjoint solver requiresmore time and due to the approximations, and the frozen turbulence, the residuals are not gettingas small as for the primal variables. Instead the Ua velocity is monitored, and the simulation isterminated when stability is achieved.

functions minMaxUa

type fieldMinMax;functionObjectLibs ( "libfieldFunctionObjects.so" );enabled true;// outputControl outputTime;outputControl timeStep;outputInterval 1;

fields(

Ua

24

Page 26: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

3.4. RUNNING THE CASE CHAPTER 3. SETTING UP A CASE

);

Listing 3.6: Part of the controlDict file

In the listing 3.6, the user function to see the minMaxUa is shown to give an idea of the stability ofthe adjoint velocity.

3.3.2 fvSolution

The fvSolution file is quite similar to the one in the tutorial of adjointShapeOptimizationFoamwhich is described in Ulf Nilssons work. [3]

The difference with respect to this project is the addition of the solution for the displacementwhich is defined in the following lines in listing 3.7.

cellMotionU

solver PCG;preconditioner DIC;tolerance 1e-8;relTol 0;

cellDisplacement

solver PCG;preconditioner DIC;tolerance 1e-8;relTol 0;

Listing 3.7: Part of the fvSolution file

3.4 Running the case

What follows below is an Allrun script that runs the simulation for one iteration. For more iterationsthe times need to be changed. The script can be found in the course homepage.

#!/bin/sh

cd $0%/* || exit 1 # run from this directory

# Source tutorial run functions

. $WM_PROJECT_DIR/bin/tools/RunFunctions

runApplication blockMesh # run blockmesh

setSet -batch system/batchSetSet > log.setSet #Set up the sets

runApplication decomposePar #Decompose for the run parallel

runParallel simpleFoam 4 #Run simpleFoam on 4 cores

#Copy the pointdisplacement to the latest time

cp processor0/0/pointDisplacement processor0/5000

cp processor1/0/pointDisplacement processor1/5000

cp processor2/0/pointDisplacement processor2/5000

25

Page 27: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

3.4. RUNNING THE CASE CHAPTER 3. SETTING UP A CASE

cp processor3/0/pointDisplacement processor3/5000

#Copy the Ua to the latest time

cp processor0/0/Ua processor0/5000

cp processor1/0/Ua processor1/5000

cp processor2/0/Ua processor2/5000

cp processor3/0/Ua processor3/5000

#Copy the pa to the latest time

cp processor0/0/pa processor0/5000

cp processor1/0/pa processor1/5000

cp processor2/0/pa processor2/5000

cp processor3/0/pa processor3/5000

#change endtime

sed -i s/"\(endTime[ \t]*\) 5000;"/"\1 17000;"/g system/controlDict

sed -i s/"0.5"/"0.15"/g system/fvSolution #underRelaxation for the pa

sed -i s/"0.75"/"0.2"/g system/fvSolution #underRelaxation for the Ua

runParallel adjointSensitivityFoam 4 #Run adjoint sensitivityFoam on 4 cores

#Copy the pointdisplacement to the latest time

cp processor0/5000/pointDisplacement processor0/17000

cp processor1/5000/pointDisplacement processor1/17000

cp processor2/5000/pointDisplacement processor2/17000

cp processor3/5000/pointDisplacement processor3/17000

#Change endtime

sed -i s/"\(endTime[ \t]*\) 17000;"/"\1 17010;"/g system/controlDict

#change runintreval

sed -i s/"\(writeInterval[ \t]*\) 1000;"/"\1 10;"/g system/controlDict

runParallel sensitivityMoveMesh 4 #Run sensitivityMovemesh

#change endtime

sed -i s/"\(endTime[ \t]*\) 17010;"/"\1 20000;"/g system/controlDict

sed -i s/"0.15"/"0.5"/g system/fvSolution #underRelaxation for the pa/p

sed -i s/"0.2"/"0.75"/g system/fvSolution #underRelaxation for the Ua/U

runParallel simpleFoam 4 #Run simpleFoam on 4 cores

runApplication reconstructPar #Reconstruct

runApplication lighthillCostFunction

# ----------------------------------------------------------------- end-of-file

26

Page 28: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

Chapter 4

Results

In this section the results of the case boxWindCase will be presented. Two different values of gammawere tested for three iterations. Both of the gamma values ended up with cost function valueshigher then the original one, though after the first iteration both cases showed a decrese in theaerodynamically induced wind noise.

start first iteration second iteration third iterationgamma = 1e− 5 -847618 [1/m2] -846094 [1/m2] -848499 [1/m2] -855135 [1/m2]gamma = 5e− 6 -847618 [1/m2] -816134 [1/m2] -851543 [1/m2] -857076 [1/m2]

Table 4.1: The value of the cost function for the different gamma values at different iteration

In the table 4.1, the results of the noise level are shown. The first iteration for both cases shows areduction of the Lighthill stress tensor, and the reduction is greatest for the case with gamma = 5e−6.After the first iteration the cost functon increased greatly.

In the figure 4.1, the displacement is shown for the case with gamma = 5e− 6, colored by the sensi-tivity field. The front of the box is creating an ”edge”, and the back of the box is ”rounded”.

In the figure 4.2, the displacement is shown for the case with gamma = 1e− 5, colored by the sensi-tivity field. The front of the box is creating an ”edge” and the back of the box is ”rounded”. Notethat they look very similar.

The figure 4.3 is showing the back of the box more clearly. The result is shown for the case withgamma = 5e− 6 although the two cases look very similar. Note the small edge that is created.

27

Page 29: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

CHAPTER 4. RESULTS

(a) (b)

(c)

Figure 4.1: The box after displacement colored with the sensitivity for the case with gamma = 5e − 6. a)after first displacement b) after second displacement c) after third displacement.

28

Page 30: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

CHAPTER 4. RESULTS

(a) (b)

(c)

Figure 4.2: The box after displacement colored with the sensitivity for the case with gamma = 1e − 5. a)after first displacement b) after second displacement c) after third displacement.

29

Page 31: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

CHAPTER 4. RESULTS

(a) (b)

(c)

Figure 4.3: The back of the box after displacement colored with the sensitivity for the case with gamma =5e− 6. a) after first displacement b) after second displacement c) after third displacement.

30

Page 32: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

Chapter 5

Discussion

It is not surprise that the costfunction eventually after decreasing a bit in the first iteration latergot up. In the work at Volvo, the decrease in the cost function for a square cube was only decreasedwith 0.23%, and that with the cell displacement done in the commercial software ANSA [1].

It is somewhat of a surprise that the small differences in displacement in the two cases gives sobig differences in the costfunction. This would indicate that the costfunction is very sensitive forgeometry change, and maybe that the sensitivityMoveMesh is a too crude instrument to move themesh.

5.1 adjointSensitivityFoam

In the adjointSensitivityFoam solver some problems have been found and corrected, especiallyin the adjointOutletVelocityFvPatchVectorField.C, shown in section 2.1.4. Still no significantimprovement has been shown. It is not out of the question that some of these changes, even thoughmotivated, are wrong, and that the solver is better without them. It is also a possible that thereare still some issues with the solver that are not found yet.

5.1.1 laplacian(gamma,U)

The addition to the adjointSensitivityFoam solver, the laplacian(gamma,U), has been of interestduring the project. The interpretation was first interpreted as the physical quantity ν, but asthe derivation seemed strange some test was preformed to analyse if the quantity could have adifferent, better value. As it can be seen in the results, after the first iteration for the case with thegamma = 5e − 6, roughly half of the physical ν was shown to be better. Therefore it seems that itcan be a different optimal value of gamma then 1e − 5. The dimensions of the constant need to bethe same as ν due to the dimensional check that OpenFOAM preforms before running the code.

5.2 sensitivityMoveMesh problems

The reason for the somehow bad result lies probably with the sensitivityMoveMesh solver. Whileit solves the geometry change acceptably, it always create a small edge at the back of the box thatcan be seen in Fig. 4.3. The effect of the edge on the cost function is not fully determined, but it isnot a big stretch to assume it has an adverse effect on the noise level.

31

Page 33: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

5.3. FROZEN TURBULENCE CHAPTER 5. DISCUSSION

5.2.1 alpha value

The alpha value in the change of the geometry is important. In listing 2.16 we can see that thedisplacement function looks like:

displacement = displacement old− alpha value ∗ sensitivity ∗ normal vector (5.1)

As it can see in the Eq. (5.1) the alpha value scales the sensitivity. It was set to 0.00006. It is likelythat this is not the optimal value of alpha, and that the value should even vary during the iterationsand decrease. The sensitivity is rescaled to be a maximum of 1 every iteration so that a decreasinggradient effect, which would normally be seen in an optimization problem, is not present. Thereforeit would be of great interest to investigate further the optimization of the sensitivityMoveMesh

solver.

5.3 Frozen turbulence

The adjoint solvers residuals are not getting very low and the underrelaxation factors are set verylow to make sure the solution is not diverging. This might due to the approximation of frozenturbulenze, meaning that the νeff is not changing when the adjoint field is calculated. Some workcould be done in analyzing if there is a way to update the νeff as the adjoint solver is working, toincrease both the accuracy, and possibly also the stability of the solution.

32

Page 34: Project work: Despcription of an adjoint method for object ...hani/kurser/OS_CFD_2014/Simon... · Despcription of an adjoint method for object optimization related to wind noise Developed

Bibliography

[1] Christian Sihvo. “Numerical method for Shape optimization from wind noise perspective”. MAthesis. Lulea University of Technology, 2014.

[2] Jonas Ask. “Predictions of Aerodynamically Induced Wind Noise Around Ground Vehicles”.PhD thesis. Chalmers University of Technology, 2008.

[3] Ulf Nilsson. Description of adjointShapeOptimizationFoam and how to implement new objec-tive functions. Report for the course CFD with OpenSource software. Chalmers University ofTechnology, 2014.

[4] Othmer C. “A continuous adjoint formulation for the computation of topological and surfacesensitives of ducted flows”. In: Int. J. Numer. Meth. Fluid 58 (2008), pp. 861–877.

[5] Moving boundary problem based on calculated data. Online; accessed 27 October 2014. http://www.cfd-online.com/Forums/openfoam-programming-development/122557-moving-

boundary-problem-based-calculated-data.html: CFD online, 2013.

33