DAFunctionWallHeatFlux.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v4
5 
6 \*---------------------------------------------------------------------------*/
7 
9 
10 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
11 
12 namespace Foam
13 {
14 
15 defineTypeNameAndDebug(DAFunctionWallHeatFlux, 0);
16 addToRunTimeSelectionTable(DAFunction, DAFunctionWallHeatFlux, dictionary);
17 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
18 
20  const fvMesh& mesh,
21  const DAOption& daOption,
22  const DAModel& daModel,
23  const DAIndex& daIndex,
24  const word functionName)
25  : DAFunction(
26  mesh,
27  daOption,
28  daModel,
29  daIndex,
30  functionName),
31  wallHeatFlux_(
32  IOobject(
33  "wallHeatFlux",
34  mesh.time().timeName(),
35  mesh,
36  IOobject::NO_READ,
37  IOobject::AUTO_WRITE),
38  mesh,
39  dimensionedScalar("wallHeatFlux", dimensionSet(0, 0, 0, 0, 0, 0, 0), 0.0),
40  "calculated")
41 {
42 
43  // check and assign values for scheme and formulation
44  distanceMode_ = daOption_.getAllOptions().getWord("wallDistanceMethod");
45  if (distanceMode_ != "daCustom" && distanceMode_ != "default")
46  {
47  FatalErrorIn(" ") << "wallDistanceMethod: "
48  << distanceMode_ << " not supported!"
49  << " Options are: default and daCustom."
50  << abort(FatalError);
51  }
52  calcMode_ = functionDict_.lookupOrDefault<bool>("byUnitArea", true);
53 
54  if (mesh_.thisDb().foundObject<DATurbulenceModel>("DATurbulenceModel"))
55  {
56  DATurbulenceModel& daTurbModel =
58 
59  if (daTurbModel.getTurbModelType() == "incompressible")
60  {
61  // initialize the Prandtl number from transportProperties
62  IOdictionary transportProperties(
63  IOobject(
64  "transportProperties",
65  mesh.time().constant(),
66  mesh,
67  IOobject::MUST_READ,
68  IOobject::NO_WRITE,
69  false));
70  // for incompressible flow, we need to read Cp from transportProperties
71  if (Cp_ < 0)
72  {
73  Cp_ = readScalar(transportProperties.lookup("Cp"));
74  }
75 
76  wallHeatFlux_.dimensions().reset(dimensionSet(1, -2, 1, 1, 0, 0, 0));
77  }
78  else if (daTurbModel.getTurbModelType() == "compressible")
79  {
80  wallHeatFlux_.dimensions().reset(dimensionSet(1, 0, -3, 0, 0, 0, 0));
81  }
82  }
83  else
84  {
85  // it is solid model
86  IOdictionary solidProperties(
87  IOobject(
88  "solidProperties",
89  mesh.time().constant(),
90  mesh,
91  IOobject::MUST_READ,
92  IOobject::NO_WRITE,
93  false));
94  // for solid, we need to read k from transportProperties
95  if (k_ < 0)
96  {
97  k_ = readScalar(solidProperties.lookup("k"));
98  }
99 
100  wallHeatFlux_.dimensions().reset(dimensionSet(1, -2, 1, 1, 0, 0, 0));
101  }
102 }
103 
104 //---------- Calculate Objective Function Value ----------
106 {
107  /*
108  Description:
109  Calculate the heat flux F=k*dT/dz from the first cell. Modified based on
110  OpenFOAM/OpenFOAM-v1812/src/functionObjects/field/wallWallHeatFlux/wallWallHeatFlux.C
111 
112  Output:
113  functionValue: the sum of objective, reduced across all processors and scaled by "scale"
114  */
115 
116  // only calculate the area of all the heat flux patches if scheme is byUnitArea
117  if (calcMode_)
118  {
119  areaSum_ = 0.0;
120  forAll(faceSources_, idxI)
121  {
122  const label& functionFaceI = faceSources_[idxI];
123  label bFaceI = functionFaceI - daIndex_.nLocalInternalFaces;
124  const label patchI = daIndex_.bFacePatchI[bFaceI];
125  const label faceI = daIndex_.bFaceFaceI[bFaceI];
126  areaSum_ += mesh_.magSf().boundaryField()[patchI][faceI];
127  }
128  reduce(areaSum_, sumOp<scalar>());
129  }
130 
131  // initialize objFunValue
132  scalar functionValue = 0.0;
133 
134  volScalarField::Boundary& wallHeatFluxBf = wallHeatFlux_.boundaryFieldRef();
135 
136  // calculate HFX for fluid domain
137  if (mesh_.thisDb().foundObject<DATurbulenceModel>("DATurbulenceModel"))
138  {
139  DATurbulenceModel& daTurbModel =
141 
142  // calculate HFX for incompressible flow (no he for incompressible -> HFX = Cp * alphaEff * dT/dz)
143  if (daTurbModel.getTurbModelType() == "incompressible")
144  {
145  const objectRegistry& db = mesh_.thisDb();
146  const volScalarField& T = db.lookupObject<volScalarField>("T");
147  volScalarField alphaEff = daTurbModel.alphaEff();
148  const volScalarField::Boundary& TBf = T.boundaryField();
149  const volScalarField::Boundary& alphaEffBf = alphaEff.boundaryField();
150 
151  forAll(wallHeatFluxBf, patchI)
152  {
153  if (!wallHeatFluxBf[patchI].coupled())
154  {
155  // use OpenFOAM's snGrad()
156  if (distanceMode_ == "default")
157  {
158  wallHeatFluxBf[patchI] = Cp_ * alphaEffBf[patchI] * TBf[patchI].snGrad();
159  }
160  // use DAFOAM's custom formulation
161  else if (distanceMode_ == "daCustom")
162  {
163  forAll(wallHeatFluxBf[patchI], faceI)
164  {
165  scalar T2 = TBf[patchI][faceI];
166  label nearWallCellIndex = mesh_.boundaryMesh()[patchI].faceCells()[faceI];
167  scalar T1 = T[nearWallCellIndex];
168  vector c1 = mesh_.Cf().boundaryField()[patchI][faceI];
169  vector c2 = mesh_.C()[nearWallCellIndex];
170  scalar d = mag(c1 - c2);
171  scalar dTdz = (T2 - T1) / d;
172  wallHeatFluxBf[patchI][faceI] = Cp_ * alphaEffBf[patchI][faceI] * dTdz;
173  }
174  }
175  }
176  }
177  }
178  // calculate HFX for compressible flow (HFX = alphaEff * dHe/dz)
179  else if (daTurbModel.getTurbModelType() == "compressible")
180  {
181  fluidThermo& thermo = const_cast<fluidThermo&>(
182  mesh_.thisDb().lookupObject<fluidThermo>("thermophysicalProperties"));
183  volScalarField& he = thermo.he();
184  const volScalarField::Boundary& heBf = he.boundaryField();
185  volScalarField alphaEff = daTurbModel.alphaEff();
186  const volScalarField::Boundary& alphaEffBf = alphaEff.boundaryField();
187 
188  forAll(wallHeatFluxBf, patchI)
189  {
190  if (!wallHeatFluxBf[patchI].coupled())
191  {
192  // use OpenFOAM's snGrad()
193  if (distanceMode_ == "default")
194  {
195  wallHeatFluxBf[patchI] = alphaEffBf[patchI] * heBf[patchI].snGrad();
196  }
197  // use DAFOAM's custom formulation
198  else if (distanceMode_ == "daCustom")
199  {
200  forAll(wallHeatFluxBf[patchI], faceI)
201  {
202  scalar He2 = heBf[patchI][faceI];
203  label nearWallCellIndex = mesh_.boundaryMesh()[patchI].faceCells()[faceI];
204  scalar He1 = he[nearWallCellIndex];
205  vector c1 = mesh_.Cf().boundaryField()[patchI][faceI];
206  vector c2 = mesh_.C()[nearWallCellIndex];
207  scalar d = mag(c1 - c2);
208  scalar dHedz = (He2 - He1) / d;
209  wallHeatFluxBf[patchI][faceI] = alphaEffBf[patchI][faceI] * dHedz;
210  }
211  }
212  }
213  }
214  }
215  }
216 
217  // calculate HFX for solid domain (HFX = k * dT/dz, where k = DT / rho / Cp)
218  else
219  {
220  const objectRegistry& db = mesh_.thisDb();
221  const volScalarField& T = db.lookupObject<volScalarField>("T");
222  const volScalarField::Boundary& TBf = T.boundaryField();
223 
224  forAll(wallHeatFluxBf, patchI)
225  {
226  if (!wallHeatFluxBf[patchI].coupled())
227  {
228 
229  // use OpenFOAM's snGrad()
230  if (distanceMode_ == "default")
231  {
232  wallHeatFluxBf[patchI] = k_ * TBf[patchI].snGrad();
233  }
234  // use DAFOAM's custom formulation
235  else if (distanceMode_ == "daCustom")
236  {
237  forAll(wallHeatFluxBf[patchI], faceI)
238  {
239  scalar T2 = TBf[patchI][faceI];
240  label nearWallCellIndex = mesh_.boundaryMesh()[patchI].faceCells()[faceI];
241  scalar T1 = T[nearWallCellIndex];
242  vector c1 = mesh_.Cf().boundaryField()[patchI][faceI];
243  vector c2 = mesh_.C()[nearWallCellIndex];
244  scalar d = mag(c1 - c2);
245  scalar dTdz = (T2 - T1) / d;
246  wallHeatFluxBf[patchI][faceI] = k_ * dTdz;
247  }
248  }
249  }
250  }
251  }
252 
253  // calculate area weighted heat flux
254  scalar val = 0;
255  forAll(faceSources_, idxI)
256  {
257  const label& functionFaceI = faceSources_[idxI];
258  label bFaceI = functionFaceI - daIndex_.nLocalInternalFaces;
259  const label patchI = daIndex_.bFacePatchI[bFaceI];
260  const label faceI = daIndex_.bFaceFaceI[bFaceI];
261  scalar area = mesh_.magSf().boundaryField()[patchI][faceI];
262 
263  // represent wallHeatFlux by unit area
264  if (calcMode_)
265  {
266  val = scale_ * wallHeatFluxBf[patchI][faceI] * area / areaSum_;
267  }
268  // represent wallHeatFlux as total heat transfer through surface
269  else if (!calcMode_)
270  {
271  val = scale_ * wallHeatFluxBf[patchI][faceI] * area;
272  }
273  // error message incase of invalid entry
274  else
275  {
276  FatalErrorIn(" ") << "byUnitArea: "
277  << calcMode_ << " not supported!"
278  << " Options are: True (default) and False."
279  << abort(FatalError);
280  }
281 
282  // update obj. func. val
283  functionValue += val;
284  }
285 
286  // need to reduce the sum of force across all processors
287  reduce(functionValue, sumOp<scalar>());
288 
289  // check if we need to calculate refDiff.
290  this->calcRefVar(functionValue);
291 
292  return functionValue;
293 }
294 
295 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
296 
297 } // End namespace Foam
298 
299 // ************************************************************************* //
Foam::DAFunction::faceSources_
labelList faceSources_
a sorted list of all face sources for the objective function
Definition: DAFunction.H:67
DAFunctionWallHeatFlux.H
Foam::DAFunctionWallHeatFlux::calcMode_
bool calcMode_
if calculating flux per unit area or total, which mode to use
Definition: DAFunctionWallHeatFlux.H:44
Foam::DAIndex::bFacePatchI
labelList bFacePatchI
Definition: DAIndex.H:110
Foam::DAOption
Definition: DAOption.H:29
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(DAFunction, DAFunctionForce, dictionary)
Foam::DAFunctionWallHeatFlux::calcFunction
virtual scalar calcFunction()
calculate the value of objective function
Definition: DAFunctionWallHeatFlux.C:105
he
volScalarField & he
Definition: EEqnRhoPimple.H:5
Foam::DAFunctionWallHeatFlux::k_
scalar k_
thermal conductivity for solid heatFlux calculation
Definition: DAFunctionWallHeatFlux.H:35
thermo
fluidThermo & thermo
Definition: createRefsRhoPimple.H:6
Foam::DAFunction::calcRefVar
void calcRefVar(scalar &functionValue)
calculate (var-ref)^2
Definition: DAFunction.C:216
Foam::DAFunction::daIndex_
const DAIndex & daIndex_
DAIndex object.
Definition: DAFunction.H:52
Foam::DAOption::getAllOptions
const dictionary & getAllOptions() const
return a reference of allOptions_ dictionary
Definition: DAOption.H:56
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
Foam::DAFunction::daModel_
const DAModel & daModel_
DAModel object.
Definition: DAFunction.H:49
Foam::DAFunctionWallHeatFlux::Cp_
scalar Cp_
Cp used in incompressible heatFlux calculation.
Definition: DAFunctionWallHeatFlux.H:32
Foam::DAIndex
Definition: DAIndex.H:32
Foam::DAModel
Definition: DAModel.H:57
Foam::DAFunction
Definition: DAFunction.H:31
Foam::DAFunctionWallHeatFlux::DAFunctionWallHeatFlux
DAFunctionWallHeatFlux(const fvMesh &mesh, const DAOption &daOption, const DAModel &daModel, const DAIndex &daIndex, const word functionName)
Definition: DAFunctionWallHeatFlux.C:19
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFunction, 0)
Foam::DAFunction::daOption_
const DAOption & daOption_
DAOption object.
Definition: DAFunction.H:46
Foam
Definition: checkGeometry.C:32
T
volScalarField & T
Definition: createRefsHeatTransfer.H:5
alphaEff
volScalarField alphaEff("alphaEff", turbulencePtr_->nu()/Pr+alphat)
forAll
forAll(nuTilda1, cellI)
Definition: nuTilda1EqnIrkPimple.H:19
Foam::DATurbulenceModel::getTurbModelType
word getTurbModelType() const
Definition: DATurbulenceModel.H:260
Foam::DAIndex::nLocalInternalFaces
label nLocalInternalFaces
local internal face size
Definition: DAIndex.H:98
Foam::DATurbulenceModel
Definition: DATurbulenceModel.H:52
Foam::DAFunctionWallHeatFlux::areaSum_
scalar areaSum_
the area of all heat flux patches
Definition: DAFunctionWallHeatFlux.H:41
Foam::DATurbulenceModel::alphaEff
tmp< volScalarField > alphaEff()
return effective thermal diffusivity
Definition: DATurbulenceModel.C:233
Foam::DAModel::getDATurbulenceModel
const DATurbulenceModel & getDATurbulenceModel() const
get a reference to DATurbulenceModel
Definition: DAModel.C:176
Foam::DAFunction::functionDict_
dictionary functionDict_
dictionary containing the information for the objective function
Definition: DAFunction.H:64
Foam::DAFunctionWallHeatFlux::distanceMode_
word distanceMode_
if calculating wallHeatFlux by OpenFOAMs snGrad() or DAFOAM's custom (daCustom) formulation
Definition: DAFunctionWallHeatFlux.H:47
Foam::DAFunctionWallHeatFlux::wallHeatFlux_
volScalarField wallHeatFlux_
wall heat flux field
Definition: DAFunctionWallHeatFlux.H:38
Foam::DAFunction::scale_
scalar scale_
scale of the objective function
Definition: DAFunction.H:73
Foam::DAFunction::mesh_
const fvMesh & mesh_
fvMesh
Definition: DAFunction.H:43
Foam::DAIndex::bFaceFaceI
labelList bFaceFaceI
Definition: DAIndex.H:116