MRFZone.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2018 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "MRFZone.H"
30 #include "fvMesh.H"
31 #include "volFields.H"
32 #include "surfaceFields.H"
33 #include "fvMatrices.H"
34 #include "faceSet.H"
35 #include "geometricOneField.H"
36 #include "syncTools.H"
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42  defineTypeNameAndDebug(MRFZone, 0);
43 }
44 
45 
46 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 
48 void Foam::MRFZone::setMRFFaces()
49 {
50  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
51 
52  // Type per face:
53  // 0:not in zone
54  // 1:moving with frame
55  // 2:other
56  labelList faceType(mesh_.nFaces(), Zero);
57 
58  // Determine faces in cell zone
59  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
60  // (without constructing cells)
61 
62  const labelList& own = mesh_.faceOwner();
63  const labelList& nei = mesh_.faceNeighbour();
64 
65  // Cells in zone
66  boolList zoneCell(mesh_.nCells(), false);
67 
68  if (cellZoneID_ != -1)
69  {
70  const labelList& cellLabels = mesh_.cellZones()[cellZoneID_];
71  forAll(cellLabels, i)
72  {
73  zoneCell[cellLabels[i]] = true;
74  }
75  }
76 
77 
78  label nZoneFaces = 0;
79 
80  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
81  {
82  if (zoneCell[own[facei]] || zoneCell[nei[facei]])
83  {
84  faceType[facei] = 1;
85  nZoneFaces++;
86  }
87  }
88 
89 
90  labelHashSet excludedPatches(excludedPatchLabels_);
91 
92  forAll(patches, patchi)
93  {
94  const polyPatch& pp = patches[patchi];
95 
96  if (pp.coupled() || excludedPatches.found(patchi))
97  {
98  forAll(pp, i)
99  {
100  label facei = pp.start()+i;
101 
102  if (zoneCell[own[facei]])
103  {
104  faceType[facei] = 2;
105  nZoneFaces++;
106  }
107  }
108  }
109  else if (!isA<emptyPolyPatch>(pp))
110  {
111  forAll(pp, i)
112  {
113  label facei = pp.start()+i;
114 
115  if (zoneCell[own[facei]])
116  {
117  faceType[facei] = 1;
118  nZoneFaces++;
119  }
120  }
121  }
122  }
123 
124  // Synchronize the faceType across processor patches
125  syncTools::syncFaceList(mesh_, faceType, maxEqOp<label>());
126 
127  // Now we have for faceType:
128  // 0 : face not in cellZone
129  // 1 : internal face or normal patch face
130  // 2 : coupled patch face or excluded patch face
131 
132  // Sort into lists per patch.
133 
134  internalFaces_.setSize(mesh_.nFaces());
135  label nInternal = 0;
136 
137  for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
138  {
139  if (faceType[facei] == 1)
140  {
141  internalFaces_[nInternal++] = facei;
142  }
143  }
144  internalFaces_.setSize(nInternal);
145 
146  labelList nIncludedFaces(patches.size(), Zero);
147  labelList nExcludedFaces(patches.size(), Zero);
148 
149  forAll(patches, patchi)
150  {
151  const polyPatch& pp = patches[patchi];
152 
153  forAll(pp, patchFacei)
154  {
155  label facei = pp.start() + patchFacei;
156 
157  if (faceType[facei] == 1)
158  {
159  nIncludedFaces[patchi]++;
160  }
161  else if (faceType[facei] == 2)
162  {
163  nExcludedFaces[patchi]++;
164  }
165  }
166  }
167 
168  includedFaces_.setSize(patches.size());
169  excludedFaces_.setSize(patches.size());
170  forAll(nIncludedFaces, patchi)
171  {
172  includedFaces_[patchi].setSize(nIncludedFaces[patchi]);
173  excludedFaces_[patchi].setSize(nExcludedFaces[patchi]);
174  }
175  nIncludedFaces = 0;
176  nExcludedFaces = 0;
177 
178  forAll(patches, patchi)
179  {
180  const polyPatch& pp = patches[patchi];
181 
182  forAll(pp, patchFacei)
183  {
184  label facei = pp.start() + patchFacei;
185 
186  if (faceType[facei] == 1)
187  {
188  includedFaces_[patchi][nIncludedFaces[patchi]++] = patchFacei;
189  }
190  else if (faceType[facei] == 2)
191  {
192  excludedFaces_[patchi][nExcludedFaces[patchi]++] = patchFacei;
193  }
194  }
195  }
196 
197 
198  if (debug)
199  {
200  faceSet internalFaces(mesh_, "internalFaces", internalFaces_);
201  Pout<< "Writing " << internalFaces.size()
202  << " internal faces in MRF zone to faceSet "
203  << internalFaces.name() << endl;
204  internalFaces.write();
205 
206  faceSet MRFFaces(mesh_, "includedFaces", 100);
207  forAll(includedFaces_, patchi)
208  {
209  forAll(includedFaces_[patchi], i)
210  {
211  label patchFacei = includedFaces_[patchi][i];
212  MRFFaces.insert(patches[patchi].start()+patchFacei);
213  }
214  }
215  Pout<< "Writing " << MRFFaces.size()
216  << " patch faces in MRF zone to faceSet "
217  << MRFFaces.name() << endl;
218  MRFFaces.write();
219 
220  faceSet excludedFaces(mesh_, "excludedFaces", 100);
221  forAll(excludedFaces_, patchi)
222  {
223  forAll(excludedFaces_[patchi], i)
224  {
225  label patchFacei = excludedFaces_[patchi][i];
226  excludedFaces.insert(patches[patchi].start()+patchFacei);
227  }
228  }
229  Pout<< "Writing " << excludedFaces.size()
230  << " faces in MRF zone with special handling to faceSet "
231  << excludedFaces.name() << endl;
232  excludedFaces.write();
233  }
234 }
235 
236 
237 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
238 
239 Foam::MRFZone::MRFZone
240 (
241  const word& name,
242  const fvMesh& mesh,
243  const dictionary& dict,
244  const word& cellZoneName
245 )
246 :
247  mesh_(mesh),
248  name_(name),
249  coeffs_(dict),
250  active_(coeffs_.lookupOrDefault("active", true)),
251  cellZoneName_(cellZoneName),
252  cellZoneID_(),
253  excludedPatchNames_
254  (
255  coeffs_.lookupOrDefault<wordRes>("nonRotatingPatches", wordRes())
256  ),
257  origin_(coeffs_.lookup("origin")),
258  axis_(coeffs_.lookup("axis")),
259  omega_(Function1<scalar>::New("omega", coeffs_))
260 {
261  if (cellZoneName_ == word::null)
262  {
263  coeffs_.readEntry("cellZone", cellZoneName_);
264  }
265 
266  if (!active_)
267  {
268  cellZoneID_ = -1;
269  }
270  else
271  {
272  cellZoneID_ = mesh_.cellZones().findZoneID(cellZoneName_);
273 
274  axis_ = axis_/mag(axis_);
275 
276  const labelHashSet excludedPatchSet
277  (
278  mesh_.boundaryMesh().patchSet(excludedPatchNames_)
279  );
280 
281  excludedPatchLabels_.setSize(excludedPatchSet.size());
282 
283  label i = 0;
284  for (const label patchi : excludedPatchSet)
285  {
286  excludedPatchLabels_[i++] = patchi;
287  }
288 
289  bool cellZoneFound = (cellZoneID_ != -1);
290 
291  reduce(cellZoneFound, orOp<bool>());
292 
293  if (!cellZoneFound)
294  {
296  << "cannot find MRF cellZone " << cellZoneName_
297  << exit(FatalError);
298  }
299 
300  setMRFFaces();
301  }
302 }
303 
304 
305 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
306 
308 {
309  return omega_->value(mesh_.time().timeOutputValue())*axis_;
310 }
311 
312 
314 (
315  const volVectorField& U,
316  volVectorField& ddtU
317 ) const
318 {
319  if (cellZoneID_ == -1)
320  {
321  return;
322  }
323 
324  const labelList& cells = mesh_.cellZones()[cellZoneID_];
325  vectorField& ddtUc = ddtU.primitiveFieldRef();
326  const vectorField& Uc = U;
327 
328  const vector Omega = this->Omega();
329 
330  forAll(cells, i)
331  {
332  label celli = cells[i];
333  ddtUc[celli] += (Omega ^ Uc[celli]);
334  }
335 }
336 
337 
338 void Foam::MRFZone::addCoriolis(fvVectorMatrix& UEqn, const bool rhs) const
339 {
340  if (cellZoneID_ == -1)
341  {
342  return;
343  }
344 
345  const labelList& cells = mesh_.cellZones()[cellZoneID_];
346  const scalarField& V = mesh_.V();
347  vectorField& Usource = UEqn.source();
348  const vectorField& U = UEqn.psi();
349 
350  const vector Omega = this->Omega();
351 
352  if (rhs)
353  {
354  forAll(cells, i)
355  {
356  label celli = cells[i];
357  Usource[celli] += V[celli]*(Omega ^ U[celli]);
358  }
359  }
360  else
361  {
362  forAll(cells, i)
363  {
364  label celli = cells[i];
365  Usource[celli] -= V[celli]*(Omega ^ U[celli]);
366  }
367  }
368 }
369 
370 
372 (
373  const volScalarField& rho,
375  const bool rhs
376 ) const
377 {
378  if (cellZoneID_ == -1)
379  {
380  return;
381  }
382 
383  const labelList& cells = mesh_.cellZones()[cellZoneID_];
384  const scalarField& V = mesh_.V();
385  vectorField& Usource = UEqn.source();
386  const vectorField& U = UEqn.psi();
387 
388  const vector Omega = this->Omega();
389 
390  if (rhs)
391  {
392  forAll(cells, i)
393  {
394  label celli = cells[i];
395  Usource[celli] += V[celli]*rho[celli]*(Omega ^ U[celli]);
396  }
397  }
398  else
399  {
400  forAll(cells, i)
401  {
402  label celli = cells[i];
403  Usource[celli] -= V[celli]*rho[celli]*(Omega ^ U[celli]);
404  }
405  }
406 }
407 
408 
410 {
411  if (cellZoneID_ == -1)
412  {
413  return;
414  }
415 
416  const volVectorField& C = mesh_.C();
417 
418  const vector Omega = this->Omega();
419 
420  const labelList& cells = mesh_.cellZones()[cellZoneID_];
421 
422  forAll(cells, i)
423  {
424  label celli = cells[i];
425  U[celli] -= (Omega ^ (C[celli] - origin_));
426  }
427 
428  // Included patches
429 
430  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
431 
432  forAll(includedFaces_, patchi)
433  {
434  forAll(includedFaces_[patchi], i)
435  {
436  label patchFacei = includedFaces_[patchi][i];
437  Ubf[patchi][patchFacei] = Zero;
438  }
439  }
440 
441  // Excluded patches
442  forAll(excludedFaces_, patchi)
443  {
444  forAll(excludedFaces_[patchi], i)
445  {
446  label patchFacei = excludedFaces_[patchi][i];
447  Ubf[patchi][patchFacei] -=
448  (Omega
449  ^ (C.boundaryField()[patchi][patchFacei] - origin_));
450  }
451  }
452 }
453 
454 
456 {
457  makeRelativeRhoFlux(geometricOneField(), phi);
458 }
459 
460 
462 {
463  makeRelativeRhoFlux(oneFieldField(), phi);
464 }
465 
466 
468 {
469  makeRelativeRhoFlux(oneField(), phi, patchi);
470 }
471 
472 
474 (
475  const surfaceScalarField& rho,
477 ) const
478 {
479  makeRelativeRhoFlux(rho, phi);
480 }
481 
482 
484 {
485  if (cellZoneID_ == -1)
486  {
487  return;
488  }
489 
490  const volVectorField& C = mesh_.C();
491 
492  const vector Omega = this->Omega();
493 
494  const labelList& cells = mesh_.cellZones()[cellZoneID_];
495 
496  forAll(cells, i)
497  {
498  label celli = cells[i];
499  U[celli] += (Omega ^ (C[celli] - origin_));
500  }
501 
502  // Included patches
503  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
504 
505  forAll(includedFaces_, patchi)
506  {
507  forAll(includedFaces_[patchi], i)
508  {
509  label patchFacei = includedFaces_[patchi][i];
510  Ubf[patchi][patchFacei] =
511  (Omega ^ (C.boundaryField()[patchi][patchFacei] - origin_));
512  }
513  }
514 
515  // Excluded patches
516  forAll(excludedFaces_, patchi)
517  {
518  forAll(excludedFaces_[patchi], i)
519  {
520  label patchFacei = excludedFaces_[patchi][i];
521  Ubf[patchi][patchFacei] +=
522  (Omega ^ (C.boundaryField()[patchi][patchFacei] - origin_));
523  }
524  }
525 }
526 
527 
529 {
530  makeAbsoluteRhoFlux(geometricOneField(), phi);
531 }
532 
533 
535 (
536  const surfaceScalarField& rho,
538 ) const
539 {
540  makeAbsoluteRhoFlux(rho, phi);
541 }
542 
543 
545 {
546  if (!active_)
547  {
548  return;
549  }
550 
551  const vector Omega = this->Omega();
552 
553  // Included patches
554  volVectorField::Boundary& Ubf = U.boundaryFieldRef();
555 
556  forAll(includedFaces_, patchi)
557  {
558  const vectorField& patchC = mesh_.Cf().boundaryField()[patchi];
559 
560  vectorField pfld(Ubf[patchi]);
561 
562  forAll(includedFaces_[patchi], i)
563  {
564  label patchFacei = includedFaces_[patchi][i];
565 
566  pfld[patchFacei] = (Omega ^ (patchC[patchFacei] - origin_));
567  }
568 
569  Ubf[patchi] == pfld;
570  }
571 }
572 
573 
575 {
576  os << nl;
577  os.beginBlock(name_);
578 
579  os.writeEntry("active", active_);
580  os.writeEntry("cellZone", cellZoneName_);
581  os.writeEntry("origin", origin_);
582  os.writeEntry("axis", axis_);
583  omega_->writeData(os);
584 
585  if (excludedPatchNames_.size())
586  {
587  os.writeEntry("nonRotatingPatches", excludedPatchNames_);
588  }
589 
590  os.endBlock();
591 }
592 
593 
595 {
596  coeffs_ = dict;
597 
598  active_ = coeffs_.lookupOrDefault("active", true);
599  coeffs_.readEntry("cellZone", cellZoneName_);
600  cellZoneID_ = mesh_.cellZones().findZoneID(cellZoneName_);
601 
602  return true;
603 }
604 
605 
607 {
608  if (mesh_.topoChanging())
609  {
610  setMRFFaces();
611  }
612 }
613 
614 
615 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
volFields.H
Foam::oneFieldField
A class representing the concept of a field of oneFields used to avoid unnecessary manipulations for ...
Definition: oneFieldField.H:53
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::FieldField
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:53
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::primitiveMesh::nFaces
label nFaces() const
Number of mesh faces.
Definition: primitiveMeshI.H:90
MRFZone.H
Foam::geometricOneField
A class representing the concept of a GeometricField of 1 used to avoid unnecessary manipulations for...
Definition: geometricOneField.H:54
Foam::MRFZone::makeAbsolute
void makeAbsolute(volVectorField &U) const
Make the given relative velocity absolute within the MRF region.
Definition: MRFZone.C:483
Foam::polyMesh::cellZones
const cellZoneMesh & cellZones() const
Return cell zone mesh.
Definition: polyMesh.H:483
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:72
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
surfaceFields.H
Foam::surfaceFields.
Foam::Ostream::beginBlock
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:91
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.H:1241
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
Foam::HashSet< label, Hash< label > >
rho
rho
Definition: readInitialConditions.H:96
syncTools.H
Foam::fvMatrix::psi
const GeometricField< Type, fvPatchField, volMesh > & psi() const
Definition: fvMatrix.H:285
Foam::Function1
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Definition: Function1.H:56
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
fvMatrices.H
A special matrix type and solver, designed for finite volume solutions of scalar equations.
Foam::MRFZone::read
bool read(const dictionary &dict)
Read MRF dictionary.
Definition: MRFZone.C:594
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::syncTools::syncFaceList
static void syncFaceList(const polyMesh &mesh, UList< T > &faceValues, const CombineOp &cop)
Synchronize values on all mesh faces.
Definition: syncTools.H:390
Foam::primitiveMesh::nCells
label nCells() const
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::label
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:62
Foam::Field< vector >
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:91
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1076
faceSet.H
phi
surfaceScalarField & phi
Definition: setRegionFluidFields.H:8
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::Ostream::endBlock
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:109
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::C::C
C()
Construct null.
Definition: C.C:43
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::MRFZone::writeData
void writeData(Ostream &os) const
Write.
Definition: MRFZone.C:574
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::GeometricField::primitiveFieldRef
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field.
Definition: GeometricField.C:735
Foam::MRFZone::Omega
vector Omega() const
Return the current Omega vector.
Definition: MRFZone.C:307
Foam::MRFZone::correctBoundaryVelocity
void correctBoundaryVelocity(volVectorField &U) const
Correct the boundary velocity for the rotation of the MRF region.
Definition: MRFZone.C:544
U
U
Definition: pEqn.H:72
Foam::MRFZone::makeRelative
void makeRelative(volVectorField &U) const
Make the given absolute velocity relative within the MRF region.
Definition: MRFZone.C:409
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
geometricOneField.H
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::Vector< scalar >
Foam::List< label >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
Foam::fvMatrix::source
Field< Type > & source()
Definition: fvMatrix.H:295
Foam::oneField
A class representing the concept of a field of 1 used to avoid unnecessary manipulations for objects ...
Definition: oneField.H:53
Foam::wordRes
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:51
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::fvMatrix
A special matrix type and solver, designed for finite volume solutions of scalar equations....
Definition: fvPatchField.H:76
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:219
UEqn
fvVectorMatrix & UEqn
Definition: UEqn.H:13
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::C
Graphite solid properties.
Definition: C.H:50
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys and label hasher.
Definition: HashSet.H:415
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::GeometricField< vector, fvPatchField, volMesh >
Foam::orOp
Definition: ops.H:234
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::MRFZone::update
void update()
Update MRFZone faces if the mesh topology changes.
Definition: MRFZone.C:606
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1082
Foam::MRFZone::addCoriolis
void addCoriolis(const volVectorField &U, volVectorField &ddtU) const
Add the Coriolis force contribution to the acceleration field.
Definition: MRFZone.C:314