1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
29 #include "volFields.H"
30 #include "surfaceFields.H"
31 #include "fvMatrices.H"
32 #include "syncTools.H"
34 #include "geometricOneField.H"
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 defineTypeNameAndDebug(Foam::MRFZone, 0);
41 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 void Foam::MRFZone::setMRFFaces()
45 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
49 // 1:moving with frame
51 labelList faceType(mesh_.nFaces(), 0);
53 // Determine faces in cell zone
54 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 // (without constructing cells)
57 const labelList& own = mesh_.faceOwner();
58 const labelList& nei = mesh_.faceNeighbour();
61 boolList zoneCell(mesh_.nCells(), false);
63 if (cellZoneID_ != -1)
65 const labelList& cellLabels = mesh_.cellZones()[cellZoneID_];
68 zoneCell[cellLabels[i]] = true;
75 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
77 if (zoneCell[own[faceI]] || zoneCell[nei[faceI]])
85 labelHashSet excludedPatches(excludedPatchLabels_);
87 forAll(patches, patchI)
89 const polyPatch& pp = patches[patchI];
91 if (pp.coupled() || excludedPatches.found(patchI))
95 label faceI = pp.start()+i;
97 if (zoneCell[own[faceI]])
104 else if (!isA<emptyPolyPatch>(pp))
108 label faceI = pp.start()+i;
110 if (zoneCell[own[faceI]])
119 // Now we have for faceType:
120 // 0 : face not in cellZone
121 // 1 : internal face or normal patch face
122 // 2 : coupled patch face or excluded patch face
124 // Sort into lists per patch.
126 internalFaces_.setSize(mesh_.nFaces());
129 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
131 if (faceType[faceI] == 1)
133 internalFaces_[nInternal++] = faceI;
136 internalFaces_.setSize(nInternal);
138 labelList nIncludedFaces(patches.size(), 0);
139 labelList nExcludedFaces(patches.size(), 0);
141 forAll(patches, patchi)
143 const polyPatch& pp = patches[patchi];
145 forAll(pp, patchFacei)
147 label faceI = pp.start()+patchFacei;
149 if (faceType[faceI] == 1)
151 nIncludedFaces[patchi]++;
153 else if (faceType[faceI] == 2)
155 nExcludedFaces[patchi]++;
160 includedFaces_.setSize(patches.size());
161 excludedFaces_.setSize(patches.size());
162 forAll(nIncludedFaces, patchi)
164 includedFaces_[patchi].setSize(nIncludedFaces[patchi]);
165 excludedFaces_[patchi].setSize(nExcludedFaces[patchi]);
170 forAll(patches, patchi)
172 const polyPatch& pp = patches[patchi];
174 forAll(pp, patchFacei)
176 label faceI = pp.start()+patchFacei;
178 if (faceType[faceI] == 1)
180 includedFaces_[patchi][nIncludedFaces[patchi]++] = patchFacei;
182 else if (faceType[faceI] == 2)
184 excludedFaces_[patchi][nExcludedFaces[patchi]++] = patchFacei;
192 faceSet internalFaces(mesh_, "internalFaces", internalFaces_);
193 Pout<< "Writing " << internalFaces.size()
194 << " internal faces in MRF zone to faceSet "
195 << internalFaces.name() << endl;
196 internalFaces.write();
198 faceSet MRFFaces(mesh_, "includedFaces", 100);
199 forAll(includedFaces_, patchi)
201 forAll(includedFaces_[patchi], i)
203 label patchFacei = includedFaces_[patchi][i];
204 MRFFaces.insert(patches[patchi].start()+patchFacei);
207 Pout<< "Writing " << MRFFaces.size()
208 << " patch faces in MRF zone to faceSet "
209 << MRFFaces.name() << endl;
212 faceSet excludedFaces(mesh_, "excludedFaces", 100);
213 forAll(excludedFaces_, patchi)
215 forAll(excludedFaces_[patchi], i)
217 label patchFacei = excludedFaces_[patchi][i];
218 excludedFaces.insert(patches[patchi].start()+patchFacei);
221 Pout<< "Writing " << excludedFaces.size()
222 << " faces in MRF zone with special handling to faceSet "
223 << excludedFaces.name() << endl;
224 excludedFaces.write();
229 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
231 Foam::MRFZone::MRFZone(const fvMesh& mesh, Istream& is)
236 cellZoneID_(mesh_.cellZones().findZoneID(name_)),
239 dict_.lookupOrDefault("nonRotatingPatches", wordList(0))
241 origin_(dict_.lookup("origin")),
242 axis_(dict_.lookup("axis")),
243 omega_(dict_.lookup("omega")),
244 Omega_("Omega", omega_*axis_)
246 if (dict_.found("patches"))
248 WarningIn("MRFZone(const fvMesh&, Istream&)")
249 << "Ignoring entry 'patches'\n"
250 << " By default all patches within the rotating region rotate.\n"
251 << " Optionally supply excluded patches using 'nonRotatingPatches'."
255 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
257 axis_ = axis_/mag(axis_);
258 Omega_ = omega_*axis_;
260 excludedPatchLabels_.setSize(excludedPatchNames_.size());
262 forAll(excludedPatchNames_, i)
264 excludedPatchLabels_[i] = patches.findPatchID(excludedPatchNames_[i]);
266 if (excludedPatchLabels_[i] == -1)
270 "Foam::MRFZone::MRFZone(const fvMesh&, Istream&)"
271 ) << "cannot find MRF patch " << excludedPatchNames_[i]
277 bool cellZoneFound = (cellZoneID_ != -1);
278 reduce(cellZoneFound, orOp<bool>());
284 "Foam::MRFZone::MRFZone(const fvMesh&, Istream&)"
285 ) << "cannot find MRF cellZone " << name_
293 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
295 void Foam::MRFZone::addCoriolis(fvVectorMatrix& UEqn) const
297 if (cellZoneID_ == -1)
302 const labelList& cells = mesh_.cellZones()[cellZoneID_];
303 const scalarField& V = mesh_.V();
304 vectorField& Usource = UEqn.source();
305 const vectorField& U = UEqn.psi();
306 const vector& Omega = Omega_.value();
310 label celli = cells[i];
311 Usource[celli] -= V[celli]*(Omega ^ U[celli]);
316 void Foam::MRFZone::addCoriolis
318 const volScalarField& rho,
322 if (cellZoneID_ == -1)
327 const labelList& cells = mesh_.cellZones()[cellZoneID_];
328 const scalarField& V = mesh_.V();
329 vectorField& Usource = UEqn.source();
330 const vectorField& U = UEqn.psi();
331 const vector& Omega = Omega_.value();
335 label celli = cells[i];
336 Usource[celli] -= V[celli]*rho[celli]*(Omega ^ U[celli]);
341 void Foam::MRFZone::relativeVelocity(volVectorField& U) const
343 const volVectorField& C = mesh_.C();
345 const vector& origin = origin_.value();
346 const vector& Omega = Omega_.value();
348 const labelList& cells = mesh_.cellZones()[cellZoneID_];
352 label celli = cells[i];
353 U[celli] -= (Omega ^ (C[celli] - origin));
357 forAll(includedFaces_, patchi)
359 forAll(includedFaces_[patchi], i)
361 label patchFacei = includedFaces_[patchi][i];
362 U.boundaryField()[patchi][patchFacei] = vector::zero;
367 forAll(excludedFaces_, patchi)
369 forAll(excludedFaces_[patchi], i)
371 label patchFacei = excludedFaces_[patchi][i];
372 U.boundaryField()[patchi][patchFacei] -=
373 (Omega ^ (C.boundaryField()[patchi][patchFacei] - origin));
379 void Foam::MRFZone::relativeFlux(surfaceScalarField& phi) const
381 relativeRhoFlux(geometricOneField(), phi);
385 void Foam::MRFZone::relativeFlux
387 const surfaceScalarField& rho,
388 surfaceScalarField& phi
391 relativeRhoFlux(rho, phi);
395 void Foam::MRFZone::absoluteFlux(surfaceScalarField& phi) const
397 absoluteRhoFlux(geometricOneField(), phi);
401 void Foam::MRFZone::absoluteFlux
403 const surfaceScalarField& rho,
404 surfaceScalarField& phi
407 absoluteRhoFlux(rho, phi);
411 void Foam::MRFZone::correctBoundaryVelocity(volVectorField& U) const
413 const vector& origin = origin_.value();
414 const vector& Omega = Omega_.value();
417 forAll(includedFaces_, patchi)
419 const vectorField& patchC = mesh_.Cf().boundaryField()[patchi];
421 vectorField pfld(U.boundaryField()[patchi]);
423 forAll(includedFaces_[patchi], i)
425 label patchFacei = includedFaces_[patchi][i];
427 pfld[patchFacei] = (Omega ^ (patchC[patchFacei] - origin));
430 U.boundaryField()[patchi] == pfld;
435 // ************************************************************************* //