DAObjFuncMeshQualityKS.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v3
5 
6 \*---------------------------------------------------------------------------*/
7 
9 
10 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
11 
12 namespace Foam
13 {
14 
15 defineTypeNameAndDebug(DAObjFuncMeshQualityKS, 0);
16 addToRunTimeSelectionTable(DAObjFunc, DAObjFuncMeshQualityKS, dictionary);
17 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
18 
20  const fvMesh& mesh,
21  const DAOption& daOption,
22  const DAModel& daModel,
23  const DAIndex& daIndex,
24  const DAResidual& daResidual,
25  const word objFuncName,
26  const word objFuncPart,
27  const dictionary& objFuncDict)
28  : DAObjFunc(
29  mesh,
30  daOption,
31  daModel,
32  daIndex,
33  daResidual,
34  objFuncName,
35  objFuncPart,
36  objFuncDict)
37 {
38  // Assign type, this is common for all objectives
39  objFuncDict_.readEntry<word>("type", objFuncType_);
40 
41  objFuncConInfo_ = {};
42 
43  objFuncDict_.readEntry<scalar>("scale", scale_);
44 
45  objFuncDict_.readEntry<scalar>("coeffKS", coeffKS_);
46 
47  objFuncDict_.readEntry<word>("metric", metric_);
48 }
49 
52  const labelList& objFuncFaceSources,
53  const labelList& objFuncCellSources,
54  scalarList& objFuncFaceValues,
55  scalarList& objFuncCellValues,
56  scalar& objFuncValue)
57 {
58  /*
59  Description:
60  Calculate the mesh quality and aggregate with the KS function
61  e.g., if metric is the faceSkewness, the objFunc value will be the
62  approximated max skewness
63 
64  Input:
65  objFuncFaceSources: List of face source (index) for this objective
66 
67  objFuncCellSources: List of cell source (index) for this objective
68 
69  Output:
70  objFuncFaceValues: the discrete value of objective for each face source (index).
71  This will be used for computing df/dw in the adjoint.
72 
73  objFuncCellValues: the discrete value of objective on each cell source (index).
74  This will be used for computing df/dw in the adjoint.
75 
76  objFuncValue: the sum of objective, reduced across all processors and scaled by "scale"
77  */
78 
79  // initialize objFunValue
80  objFuncValue = 0.0;
81 
82  if (metric_ == "faceOrthogonality")
83  {
84  // faceOrthogonality ranges from 0 to 1 and the nonOrthoAngle is acos(faceOrthogonality)
85  const scalarField faceOrthogonality(
86  polyMeshTools::faceOrthogonality(
87  mesh_,
88  mesh_.faceAreas(),
89  mesh_.cellCentres()));
90 
91  // calculate the KS mesh quality
92  forAll(faceOrthogonality, cellI)
93  {
94  objFuncValue += exp(coeffKS_ * faceOrthogonality[cellI]);
95 
96  if (objFuncValue > 1e200)
97  {
98  FatalErrorIn(" ") << "KS function summation term too large! "
99  << "Reduce coeffKS! " << abort(FatalError);
100  }
101  }
102  }
103  else if (metric_ == "nonOrthoAngle")
104  {
105  const scalarField faceOrthogonality(
106  polyMeshTools::faceOrthogonality(
107  mesh_,
108  mesh_.faceAreas(),
109  mesh_.cellCentres()));
110 
111  // Face based non ortho angle
112  scalarField nonOrthoAngle = faceOrthogonality;
113  forAll(faceOrthogonality, cellI)
114  {
115  scalar val = faceOrthogonality[cellI];
116  // bound it to less than 1.0 - 1e-6. We can't let val = 1
117  // because its derivative will be divided by zero
118  scalar boundV = 1.0 - 1e-6;
119  if (val > boundV)
120  {
121  val = boundV;
122  }
123  if (val < -boundV)
124  {
125  val = -boundV;
126  }
127  // compute non ortho angle
128  scalar angleRad = acos(val);
129  // convert rad to degree
130  scalar pi = constant::mathematical::pi;
131  scalar angleDeg = angleRad * 180.0 / pi;
132  nonOrthoAngle[cellI] = angleDeg;
133  }
134 
135  // calculate the KS mesh quality
136  forAll(nonOrthoAngle, cellI)
137  {
138 
139  objFuncValue += exp(coeffKS_ * nonOrthoAngle[cellI]);
140 
141  if (objFuncValue > 1e200)
142  {
143  FatalErrorIn(" ") << "KS function summation term too large! "
144  << "Reduce coeffKS! " << abort(FatalError);
145  }
146  }
147 
148  }
149  else if (metric_ == "faceSkewness")
150  {
151  const scalarField faceSkewness(
152  polyMeshTools::faceSkewness(
153  mesh_,
154  mesh_.points(),
155  mesh_.faceCentres(),
156  mesh_.faceAreas(),
157  mesh_.cellCentres()));
158 
159  // calculate the KS mesh quality
160  forAll(faceSkewness, cellI)
161  {
162 
163  objFuncValue += exp(coeffKS_ * faceSkewness[cellI]);
164 
165  if (objFuncValue > 1e200)
166  {
167  FatalErrorIn(" ") << "KS function summation term too large! "
168  << "Reduce coeffKS! " << abort(FatalError);
169  }
170  }
171 
172  }
173  else
174  {
175  FatalErrorIn(" ") << "metric not valid! "
176  << "Options: faceOrthogonality, nonOrthoAngle, or faceSkewness "
177  << abort(FatalError);
178  }
179 
180  // need to reduce the sum of force across all processors
181  reduce(objFuncValue, sumOp<scalar>());
182 
183  objFuncValue = log(objFuncValue) / coeffKS_;
184 
185  return;
186 }
187 
188 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
189 
190 } // End namespace Foam
191 
192 // ************************************************************************* //
Foam::DAObjFuncMeshQualityKS::DAObjFuncMeshQualityKS
DAObjFuncMeshQualityKS(const fvMesh &mesh, const DAOption &daOption, const DAModel &daModel, const DAIndex &daIndex, const DAResidual &daResidual, const word objFuncName, const word objFuncPart, const dictionary &objFuncDict)
Definition: DAObjFuncMeshQualityKS.C:19
DAObjFuncMeshQualityKS.H
Foam::DAObjFunc::objFuncType_
word objFuncType_
the type of the objective function
Definition: DAObjFunc.H:66
forAll
forAll(pseudoP.boundaryField(), patchI)
Definition: solvePseudoPEqn.H:10
Foam::DAObjFuncMeshQualityKS::calcObjFunc
virtual void calcObjFunc(const labelList &objFuncFaceSources, const labelList &objFuncCellSources, scalarList &objFuncFaceValues, scalarList &objFuncCellValues, scalar &objFuncValue)
calculate the value of objective function
Definition: DAObjFuncMeshQualityKS.C:51
Foam::DAOption
Definition: DAOption.H:29
daOption
DAOption daOption(mesh, pyOptions_)
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
Foam::DAObjFunc::mesh_
const fvMesh & mesh_
fvMesh
Definition: DAObjFunc.H:45
Foam::DAIndex
Definition: DAIndex.H:32
Foam::DAModel
Definition: DAModel.H:59
Foam
Definition: multiFreqScalarFvPatchField.C:144
Foam::DAObjFuncMeshQualityKS::coeffKS_
scalar coeffKS_
coefficient for the KS function
Definition: DAObjFuncMeshQualityKS.H:34
Foam::DAResidual
Definition: DAResidual.H:35
Foam::DAObjFuncMeshQualityKS::metric_
word metric_
which mesh quality metric to use
Definition: DAObjFuncMeshQualityKS.H:37
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFvSource, 0)
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(DAFvSource, DAFvSourceActuatorDisk, dictionary)
Foam::DAObjFunc::scale_
scalar scale_
scale of the objective function
Definition: DAObjFunc.H:87
daModel
DAModel daModel(mesh, daOption)
Foam::DAObjFunc::objFuncConInfo_
List< List< word > > objFuncConInfo_
the connectivity information for the objective function
Definition: DAObjFunc.H:93
daIndex
DAIndex daIndex(mesh, daOption, daModel)
Foam::DAObjFunc::objFuncDict_
const dictionary & objFuncDict_
dictionary containing the information for the objective function
Definition: DAObjFunc.H:69
Foam::DAObjFunc
Definition: DAObjFunc.H:33