MRFZone.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "MRFZone.H"
27 #include "MRFPatchField.H"
28 #include "fvMesh.H"
29 #include "volFields.H"
30 #include "fvMatrices.H"
31 #include "geometricOneField.H"
32 #include "faceSet.H"
33 #include "syncTools.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
40 }
41 
42 
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 
45 void Foam::MRFZone::setMRFFaces()
46 {
47  const polyBoundaryMesh& pbMesh = mesh_.boundaryMesh();
48  const fvBoundaryMesh& fvbMesh = mesh_.boundary();
49 
50  // Determine cells and faces in the MRF zone
51  boolList faceInMRF(mesh_.nFaces(), false);
52  boolList cellInMRF(mesh_.nCells(), false);
53  {
54  const labelUList MRFCells = cellSet_.cells();
55 
56  forAll(MRFCells, i)
57  {
58  cellInMRF[MRFCells[i]] = true;
59  }
60 
61  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
62  {
63  if
64  (
65  cellInMRF[mesh_.faceOwner()[facei]]
66  || cellInMRF[mesh_.faceNeighbour()[facei]]
67  )
68  {
69  faceInMRF[facei] = true;
70  }
71  }
72 
73  forAll(pbMesh, patchi)
74  {
75  forAll(pbMesh[patchi], patchFacei)
76  {
77  const label facei = pbMesh[patchi].start() + patchFacei;
78 
79  if (cellInMRF[mesh_.faceOwner()[facei]])
80  {
81  faceInMRF[facei] = true;
82  }
83  }
84  }
85  }
86 
87  // Synchronise the faceInMRF across processor patches
88  syncTools::syncFaceList(mesh_, faceInMRF, orEqOp<bool>());
89 
90  // Construct a list of all internal FV faces in the MRF zone
91  internalFaces_ =
93  (
94  SubList<bool>(faceInMRF, mesh_.nInternalFaces()),
95  true
96  );
97 
98  // Construct lists of patch FV faces in the MRF zone
99  {
100  patchFaces_.setSize(fvbMesh.size());
101 
102  forAll(fvbMesh, patchi)
103  {
104  patchFaces_[patchi].setSize(fvbMesh[patchi].size());
105  }
106 
107  labelList patchNFaces(fvbMesh.size(), 0);
108 
109  for
110  (
111  label facei = mesh_.nInternalFaces(), bFacei = 0;
112  facei < mesh_.nFaces();
113  ++ facei, ++ bFacei
114  )
115  {
116  if (!faceInMRF[facei]) continue;
117 
118  const labelUList patches = mesh_.polyBFacePatches()[bFacei];
119  const labelUList patchFaces = mesh_.polyBFacePatchFaces()[bFacei];
120 
121  forAll(patches, i)
122  {
123  patchFaces_[patches[i]][patchNFaces[patches[i]] ++] =
124  patchFaces[i];
125  }
126  }
127 
128  forAll(fvbMesh, patchi)
129  {
130  patchFaces_[patchi].setSize(patchNFaces[patchi]);
131  }
132  }
133 }
134 
135 
136 void Foam::MRFZone::checkMRFBCs(const volVectorField& U) const
137 {
138  static bool checked = false;
139 
140  if (!checked && U.nOldTimes())
141  {
142  const volVectorField::Boundary& Ubf = U.boundaryField();
143 
144  forAll(Ubf, patchi)
145  {
146  if (isA<MRFPatchField>(Ubf[patchi]))
147  {
148  return;
149  }
150  }
151 
153  << "Field " << U.name()
154  << " does not provide any MRF specific boundary conditions "
155  "for MRF region " << name() << nl
156  << " Walls rotating in the MRF region should have the "
157  "MRFnoSlip boundary condition."
158  << exit(FatalError);
159  }
160 }
161 
162 
163 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
164 
166 (
167  const word& name,
168  const fvMesh& mesh,
169  const dictionary& dict
170 )
171 :
172  mesh_(mesh),
173  name_(name),
174  coeffs_(dict),
175  cellSet_(mesh, coeffs_),
176  origin_(coeffs_.lookup("origin")),
177  axis_(coeffs_.lookup("axis")),
178  omega_(coeffs_)
179 {
180  axis_ = axis_/mag(axis_);
181  setMRFFaces();
182 }
183 
184 
185 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
186 
188 {
189  return omega_.value(mesh_.time().userTimeValue())*axis_;
190 }
191 
192 
194 (
195  const volVectorField& U,
196  volVectorField& ddtU
197 ) const
198 {
199  checkMRFBCs(U);
200 
201  const labelUList cells = cellSet_.cells();
202  vectorField& ddtUc = ddtU.primitiveFieldRef();
203  const vectorField& Uc = U;
204 
205  const vector Omega = this->Omega();
206 
207  forAll(cells, i)
208  {
209  const label celli = cells[i];
210  ddtUc[celli] += (Omega ^ Uc[celli]);
211  }
212 }
213 
214 
216 (
217  volVectorField& centrifugalAcceleration
218 ) const
219 {
220  const labelUList cells = cellSet_.cells();
221  const volVectorField& C = mesh_.C();
222  vectorField& cac = centrifugalAcceleration.primitiveFieldRef();
223 
224  const vector Omega = this->Omega();
225 
226  forAll(cells, i)
227  {
228  const label celli = cells[i];
229  cac[celli] -= Omega ^ (Omega ^ (C[celli] - origin_));
230  }
231 
232  volVectorField::Boundary& caf = centrifugalAcceleration.boundaryFieldRef();
233 
234  forAll(patchFaces_, patchi)
235  {
236  forAll(patchFaces_[patchi], i)
237  {
238  const label patchFacei = patchFaces_[patchi][i];
239  caf[patchi][patchFacei] -=
240  Omega
241  ^ (Omega ^ (C.boundaryField()[patchi][patchFacei] - origin_));
242  }
243  }
244 }
245 
246 
248 {
249  const volVectorField& C = mesh_.C();
250  const labelUList cells = cellSet_.cells();
251 
252  const vector Omega = this->Omega();
253 
254  forAll(cells, i)
255  {
256  const label celli = cells[i];
257  U[celli] -= (Omega ^ (C[celli] - origin_));
258  }
259 
260  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
261 
262  forAll(patchFaces_, patchi)
263  {
264  forAll(patchFaces_[patchi], i)
265  {
266  const label patchFacei = patchFaces_[patchi][i];
267  Ubf[patchi][patchFacei] -=
268  (Omega
269  ^ (C.boundaryField()[patchi][patchFacei] - origin_));
270  }
271  }
272 }
273 
274 
276 {
277  makeRelativeRhoFlux(geometricOneField(), phi);
278 }
279 
280 
282 {
283  makeRelativeRhoFlux(oneFieldField(), phi);
284 }
285 
286 
288 {
289  makeRelativeRhoFlux(oneField(), phi, patchi);
290 }
291 
292 
294 (
295  const surfaceScalarField& rho,
296  surfaceScalarField& phi
297 ) const
298 {
299  makeRelativeRhoFlux(rho, phi);
300 }
301 
302 
304 {
305  const vector Omega = this->Omega();
306 
307  Up -= (Omega ^ (mesh_.Cf().boundaryField()[patchi] - origin_));
308 }
309 
310 
312 {
313  const volVectorField& C = mesh_.C();
314  const labelUList cells = cellSet_.cells();
315 
316  const vector Omega = this->Omega();
317 
318  forAll(cells, i)
319  {
320  const label celli = cells[i];
321  U[celli] += (Omega ^ (C[celli] - origin_));
322  }
323 
324  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
325 
326  forAll(patchFaces_, patchi)
327  {
328  forAll(patchFaces_[patchi], i)
329  {
330  const label patchFacei = patchFaces_[patchi][i];
331  Ubf[patchi][patchFacei] +=
332  (Omega ^ (C.boundaryField()[patchi][patchFacei] - origin_));
333  }
334  }
335 }
336 
337 
339 {
340  makeAbsoluteRhoFlux(geometricOneField(), phi);
341 }
342 
343 
345 (
346  const surfaceScalarField& rho,
347  surfaceScalarField& phi
348 ) const
349 {
350  makeAbsoluteRhoFlux(rho, phi);
351 }
352 
353 
355 {
356  const vector Omega = this->Omega();
357 
358  Up += (Omega ^ (mesh_.Cf().boundaryField()[patchi] - origin_));
359 }
360 
361 
363 {
364  coeffs_ = dict;
365  cellSet_.read(coeffs_);
366  setMRFFaces();
367 
368  return true;
369 }
370 
371 
373 {
374  if (mesh_.topoChanged())
375  {
376  setMRFFaces();
377  }
378 }
379 
380 
381 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Graphite solid properties.
Definition: C.H:51
C()
Construct null.
Definition: C.C:40
Generic field type.
Definition: FieldField.H:77
Generic GeometricBoundaryField class.
Generic GeometricField class.
Internal::FieldType & primitiveFieldRef()
Return a reference to the internal field.
GeometricBoundaryField< Type, PatchField, GeoMesh > Boundary
Type of the boundary field.
Boundary & boundaryFieldRef()
Return a reference to the boundary field.
void setSize(const label)
Reset size of List.
Definition: List.C:281
MRF zone definition based on cell zone and parameters obtained from a control dictionary constructed ...
Definition: MRFZone.H:56
vector Omega() const
Return the current Omega vector.
Definition: MRFZone.C:187
bool read(const dictionary &dict)
Read MRF dictionary.
Definition: MRFZone.C:362
void makeAbsolute(volVectorField &U) const
Make the given relative velocity absolute within the MRF region.
Definition: MRFZone.C:311
MRFZone(const word &name, const fvMesh &mesh, const dictionary &dict)
Construct from fvMesh.
Definition: MRFZone.C:166
void makeRelative(volVectorField &U) const
Make the given absolute velocity relative within the MRF region.
Definition: MRFZone.C:247
void addCentrifugalAcceleration(volVectorField &centrifugalAcceleration) const
Add the centrifugal acceleration.
Definition: MRFZone.C:216
void update()
Update MRFZone faces if the mesh topology changes.
Definition: MRFZone.C:372
void addCoriolis(const volVectorField &U, volVectorField &ddtU) const
Add the Coriolis force contribution to the acceleration field.
Definition: MRFZone.C:194
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
bool read(Istream &, const bool keepHeader=false)
Read dictionary from Istream, optionally keeping the header.
Definition: dictionaryIO.C:108
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:101
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:893
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:951
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:1027
A class representing the concept of a GeometricField of 1 used to avoid unnecessary manipulations for...
A class representing the concept of a field of oneFields used to avoid unnecessary manipulations for ...
Definition: oneFieldField.H:53
A class representing the concept of a field of 1 used to avoid unnecessary manipulations for objects ...
Definition: oneField.H:53
labelUList cells() const
Return const access to the cell set.
Definition: polyCellSetI.H:43
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1387
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:403
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1393
label nCells() const
label nInternalFaces() const
label nFaces() const
static void syncFaceList(const polyMesh &mesh, UList< T > &l, const CombineOp &cop)
Synchronise values on all mesh faces.
Definition: syncTools.H:387
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
A special matrix type and solver, designed for finite volume solutions of scalar equations.
label patchi
const cellShapeList & cells
const fvPatchList & patches
U
Definition: pEqn.H:72
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
VolField< vector > volVectorField
Definition: volFieldsFwd.H:62
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
labelList findIndices(const ListType &, typename ListType::const_reference, const label start=0)
Find all occurrences of given element. Linear search.
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
dimensioned< scalar > mag(const dimensioned< Type > &)
defineTypeNameAndDebug(combustionModel, 0)
error FatalError
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
UList< label > labelUList
Definition: UList.H:65
static const char nl
Definition: Ostream.H:260
dictionary dict