MRFZoneDF.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2 
3  DAFoam : Discrete Adjoint with OpenFOAM
4  Version : v3
5 
6  Description:
7  A modified version of MRF that allows changing the rotation speed at
8  the runtime to enable derivatives wrt the rotation speed
9 
10  This class is modified from OpenFOAM's source code
11  src/finiteVolume/cfdTools/general/MRF
12 
13  OpenFOAM: The Open Source CFD Toolbox
14 
15  Copyright (C): 2011-2016 OpenFOAM Foundation
16 
17  OpenFOAM License:
18 
19  OpenFOAM is free software: you can redistribute it and/or modify it
20  under the terms of the GNU General Public License as published by
21  the Free Software Foundation, either version 3 of the License, or
22  (at your option) any later version.
23 
24  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
25  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27  for more details.
28 
29  You should have received a copy of the GNU General Public License
30  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
31 
32 \*---------------------------------------------------------------------------*/
33 
34 #include "MRFZoneDF.H"
35 #include "fvMesh.H"
36 #include "volFields.H"
37 #include "surfaceFields.H"
38 #include "fvMatrices.H"
39 #include "faceSet.H"
40 #include "geometricOneField.H"
41 #include "syncTools.H"
42 
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 
45 namespace Foam
46 {
47 defineTypeNameAndDebug(MRFZoneDF, 0);
48 }
49 
50 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 
52 void Foam::MRFZoneDF::setMRFFaces()
53 {
54  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
55 
56  // Type per face:
57  // 0:not in zone
58  // 1:moving with frame
59  // 2:other
60  labelList faceType(mesh_.nFaces(), 0);
61 
62  // Determine faces in cell zone
63  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64  // (without constructing cells)
65 
66  const labelList& own = mesh_.faceOwner();
67  const labelList& nei = mesh_.faceNeighbour();
68 
69  // Cells in zone
70  boolList zoneCell(mesh_.nCells(), false);
71 
72  if (cellZoneID_ != -1)
73  {
74  const labelList& cellLabels = mesh_.cellZones()[cellZoneID_];
75  forAll(cellLabels, i)
76  {
77  zoneCell[cellLabels[i]] = true;
78  }
79  }
80 
81  label nZoneFaces = 0;
82 
83  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
84  {
85  if (zoneCell[own[facei]] || zoneCell[nei[facei]])
86  {
87  faceType[facei] = 1;
88  nZoneFaces++;
89  }
90  }
91 
92  labelHashSet excludedPatches(excludedPatchLabels_);
93 
94  forAll(patches, patchi)
95  {
96  const polyPatch& pp = patches[patchi];
97 
98  if (pp.coupled() || excludedPatches.found(patchi))
99  {
100  forAll(pp, i)
101  {
102  label facei = pp.start() + i;
103 
104  if (zoneCell[own[facei]])
105  {
106  faceType[facei] = 2;
107  nZoneFaces++;
108  }
109  }
110  }
111  else if (!isA<emptyPolyPatch>(pp))
112  {
113  forAll(pp, i)
114  {
115  label facei = pp.start() + i;
116 
117  if (zoneCell[own[facei]])
118  {
119  faceType[facei] = 1;
120  nZoneFaces++;
121  }
122  }
123  }
124  }
125 
126  // Synchronize the faceType across processor patches
127  syncTools::syncFaceList(mesh_, faceType, maxEqOp<label>());
128 
129  // Now we have for faceType:
130  // 0 : face not in cellZone
131  // 1 : internal face or normal patch face
132  // 2 : coupled patch face or excluded patch face
133 
134  // Sort into lists per patch.
135 
136  internalFaces_.setSize(mesh_.nFaces());
137  label nInternal = 0;
138 
139  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
140  {
141  if (faceType[facei] == 1)
142  {
143  internalFaces_[nInternal++] = facei;
144  }
145  }
146  internalFaces_.setSize(nInternal);
147 
148  labelList nIncludedFaces(patches.size(), 0);
149  labelList nExcludedFaces(patches.size(), 0);
150 
151  forAll(patches, patchi)
152  {
153  const polyPatch& pp = patches[patchi];
154 
155  forAll(pp, patchFacei)
156  {
157  label facei = pp.start() + patchFacei;
158 
159  if (faceType[facei] == 1)
160  {
161  nIncludedFaces[patchi]++;
162  }
163  else if (faceType[facei] == 2)
164  {
165  nExcludedFaces[patchi]++;
166  }
167  }
168  }
169 
170  includedFaces_.setSize(patches.size());
171  excludedFaces_.setSize(patches.size());
172  forAll(nIncludedFaces, patchi)
173  {
174  includedFaces_[patchi].setSize(nIncludedFaces[patchi]);
175  excludedFaces_[patchi].setSize(nExcludedFaces[patchi]);
176  }
177  nIncludedFaces = 0;
178  nExcludedFaces = 0;
179 
180  forAll(patches, patchi)
181  {
182  const polyPatch& pp = patches[patchi];
183 
184  forAll(pp, patchFacei)
185  {
186  label facei = pp.start() + patchFacei;
187 
188  if (faceType[facei] == 1)
189  {
190  includedFaces_[patchi][nIncludedFaces[patchi]++] = patchFacei;
191  }
192  else if (faceType[facei] == 2)
193  {
194  excludedFaces_[patchi][nExcludedFaces[patchi]++] = patchFacei;
195  }
196  }
197  }
198 }
199 
200 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
201 
202 Foam::MRFZoneDF::MRFZoneDF(
203  const word& name,
204  const fvMesh& mesh,
205  const dictionary& dict,
206  const word& cellZoneName)
207  : mesh_(mesh),
208  name_(name),
209  coeffs_(dict),
210  active_(coeffs_.lookupOrDefault("active", true)),
211  cellZoneName_(cellZoneName),
212  cellZoneID_(),
213  excludedPatchNames_(
214  coeffs_.lookupOrDefault<wordRes>("nonRotatingPatches", wordRes())),
215  origin_(coeffs_.lookup("origin")),
216  axis_(coeffs_.lookup("axis")),
217  omega_(coeffs_.lookupOrDefault<scalar>("omega", 0.0))
218 {
219  if (cellZoneName_ == word::null)
220  {
221  coeffs_.readEntry("cellZone", cellZoneName_);
222  }
223 
224  if (!active_)
225  {
226  cellZoneID_ = -1;
227  }
228  else
229  {
230  cellZoneID_ = mesh_.cellZones().findZoneID(cellZoneName_);
231 
232  axis_ = axis_ / mag(axis_);
233 
234  const labelHashSet excludedPatchSet(
235  mesh_.boundaryMesh().patchSet(excludedPatchNames_));
236 
237  excludedPatchLabels_.setSize(excludedPatchSet.size());
238 
239  label i = 0;
240  for (const label patchi : excludedPatchSet)
241  {
242  excludedPatchLabels_[i++] = patchi;
243  }
244 
245  bool cellZoneFound = (cellZoneID_ != -1);
246 
247  reduce(cellZoneFound, orOp<bool>());
248 
249  if (!cellZoneFound)
250  {
251  FatalErrorInFunction
252  << "cannot find MRF cellZone " << cellZoneName_
253  << exit(FatalError);
254  }
255 
256  setMRFFaces();
257  }
258 }
259 
260 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
261 
262 Foam::vector Foam::MRFZoneDF::Omega() const
263 {
264  return omega_ * axis_;
265 }
266 
268  const volVectorField& U,
269  volVectorField& ddtU) const
270 {
271  if (cellZoneID_ == -1)
272  {
273  return;
274  }
275 
276  const labelList& cells = mesh_.cellZones()[cellZoneID_];
277  vectorField& ddtUc = ddtU.primitiveFieldRef();
278  const vectorField& Uc = U;
279 
280  const vector Omega = this->Omega();
281 
282  forAll(cells, i)
283  {
284  label celli = cells[i];
285  ddtUc[celli] += (Omega ^ Uc[celli]);
286  }
287 }
288 
289 void Foam::MRFZoneDF::makeRelative(volVectorField& U) const
290 {
291  if (cellZoneID_ == -1)
292  {
293  return;
294  }
295 
296  const volVectorField& C = mesh_.C();
297 
298  const vector Omega = this->Omega();
299 
300  const labelList& cells = mesh_.cellZones()[cellZoneID_];
301 
302  forAll(cells, i)
303  {
304  label celli = cells[i];
305  U[celli] -= (Omega ^ (C[celli] - origin_));
306  }
307 
308  // Included patches
309 
310  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
311 
312  forAll(includedFaces_, patchi)
313  {
314  forAll(includedFaces_[patchi], i)
315  {
316  label patchFacei = includedFaces_[patchi][i];
317  Ubf[patchi][patchFacei] = Zero;
318  }
319  }
320 
321  // Excluded patches
322  forAll(excludedFaces_, patchi)
323  {
324  forAll(excludedFaces_[patchi], i)
325  {
326  label patchFacei = excludedFaces_[patchi][i];
327  Ubf[patchi][patchFacei] -=
328  (Omega
329  ^ (C.boundaryField()[patchi][patchFacei] - origin_));
330  }
331  }
332 }
333 
334 void Foam::MRFZoneDF::makeRelative(surfaceScalarField& phi) const
335 {
336  makeRelativeRhoFlux(geometricOneField(), phi);
337 }
338 
339 void Foam::MRFZoneDF::makeRelative(FieldField<fvsPatchField, scalar>& phi) const
340 {
341  //makeRelativeRhoFlux(oneFieldField(), phi);
342 }
343 
344 void Foam::MRFZoneDF::makeRelative(Field<scalar>& phi, const label patchi) const
345 {
346  //makeRelativeRhoFlux(oneField(), phi, patchi);
347 }
348 
350  const surfaceScalarField& rho,
351  surfaceScalarField& phi) const
352 {
353  makeRelativeRhoFlux(rho, phi);
354 }
355 
356 void Foam::MRFZoneDF::correctBoundaryVelocity(volVectorField& U) const
357 {
358  if (!active_)
359  {
360  return;
361  }
362 
363  const vector Omega = this->Omega();
364 
365  // Included patches
366  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
367 
368  forAll(includedFaces_, patchi)
369  {
370  const vectorField& patchC = mesh_.Cf().boundaryField()[patchi];
371 
372  vectorField pfld(Ubf[patchi]);
373 
374  forAll(includedFaces_[patchi], i)
375  {
376  label patchFacei = includedFaces_[patchi][i];
377 
378  pfld[patchFacei] = (Omega ^ (patchC[patchFacei] - origin_));
379  }
380 
381  Ubf[patchi] == pfld;
382  }
383 }
384 /*
385 void Foam::MRFZoneDF::writeData(Ostream& os) const
386 {
387  // do nothing
388 }
389 
390 bool Foam::MRFZoneDF::read(const dictionary& dict)
391 {
392  // do nothing
393  return true;
394 }
395 
396 void Foam::MRFZoneDF::update()
397 {
398  if (mesh_.topoChanging())
399  {
400  setMRFFaces();
401  }
402 }
403 */
404 // ************************************************************************* //
U
U
Definition: pEqnPimpleDyM.H:60
forAll
forAll(pseudoP.boundaryField(), patchI)
Definition: solvePseudoPEqn.H:10
MRFZoneDF.H
Foam::MRFZoneDF::Omega
vector Omega() const
Definition: MRFZoneDF.C:262
Foam::MRFZoneDF::correctBoundaryVelocity
void correctBoundaryVelocity(volVectorField &U) const
Definition: MRFZoneDF.C:356
Foam::MRFZoneDF::makeRelative
void makeRelative(volVectorField &U) const
Definition: MRFZoneDF.C:289
mesh
fvMesh & mesh
Definition: createRefsHeatTransfer.H:4
phi
surfaceScalarField & phi
Definition: createRefsPimple.H:8
Foam
Definition: multiFreqScalarFvPatchField.C:144
Foam::MRFZoneDF::addCoriolis
void addCoriolis(const volVectorField &U, volVectorField &ddtU) const
Definition: MRFZoneDF.C:267
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(DAFvSource, 0)
rho
volScalarField & rho
Definition: createRefsRhoSimpleC.H:8