1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "mixerRotor.H"
27 #include "regionSplit.H"
28 #include "polyTopoChanger.H"
29 #include "slidingInterface.H"
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 void Foam::mixerRotor::addZones
36 DynamicList<pointZone*>& pz,
37 DynamicList<faceZone*>& fz,
38 DynamicList<cellZone*>& cz,
42 // Get the region of the cell containing the origin.
43 label originRegion = rs[mesh_.findNearestCell(rotatingRegionMarker_)];
45 labelList movingCells(mesh_.nCells());
46 label nMovingCells = 0;
50 if (rs[cellI] == originRegion)
52 movingCells[nMovingCells] = cellI;
57 movingCells.setSize(nMovingCells);
58 Info<< "Number of moving cells for " << name_ << ": "
59 << nMovingCells << endl;
65 "movingCellsZone" + name_,
74 // Add an empty zone for cut points
79 "cutPointZone" + name_,
87 // Do face zones for slider
90 label movingSliderIndex =
91 mesh_.boundaryMesh().findPatchID(movingSliderName_);
93 if (movingSliderIndex < 0)
95 FatalErrorIn("void mixerRotor::addZones(...) const")
96 << "Moving slider patch not found in boundary"
100 label staticSliderIndex =
101 mesh_.boundaryMesh().findPatchID(staticSliderName_);
103 if (staticSliderIndex < 0)
105 FatalErrorIn("void mixerRotor::addZones(...) const")
106 << "Static slider patch not found in boundary"
107 << abort(FatalError);
110 const polyPatch& movingSlider =
111 mesh_.boundaryMesh()[movingSliderIndex];
113 labelList isf(movingSlider.size());
117 isf[i] = movingSlider.start() + i;
124 movingSliderName_ + "Zone" + name_,
126 boolList(movingSlider.size(), false),
133 const polyPatch& staticSlider =
134 mesh_.boundaryMesh()[staticSliderIndex];
136 labelList osf(staticSlider.size());
140 osf[i] = staticSlider.start() + i;
147 staticSliderName_ + "Zone" + name_,
149 boolList(staticSlider.size(), false),
155 // Add empty zone for cut faces
160 "cutFaceZone" + name_,
171 void Foam::mixerRotor::addModifiers
177 // Add a topology modifier
178 if (useTopoSliding())
180 Info << "Adding topology modifier for rotor " << name_ << endl;
187 "mixerSlider" + name_,
190 staticSliderName_ + "Zone" + name_,
191 movingSliderName_ + "Zone" + name_,
192 "cutPointZone" + name_,
193 "cutFaceZone" + name_,
196 slidingInterface::INTEGRAL, // Edge matching algorithm
197 attachDetach_, // Attach-detach action
198 intersection::VISIBLE // Projection algorithm
207 void Foam::mixerRotor::calcMovingMask() const
209 if (movingPointsMaskPtr_)
211 FatalErrorIn("void mixerRotor::calcMovingMask() const")
212 << "point mask already calculated"
213 << abort(FatalError);
216 // Set the point mask
217 movingPointsMaskPtr_ = new scalarField(mesh_.allPoints().size(), 0);
218 scalarField& movingPointsMask = *movingPointsMaskPtr_;
220 const cellList& c = mesh_.cells();
221 const faceList& f = mesh_.allFaces();
223 const labelList& cellAddr = mesh_.cellZones()
224 [mesh_.cellZones().findZoneID("movingCellsZone" + name_)];
226 forAll (cellAddr, cellI)
228 const cell& curCell = c[cellAddr[cellI]];
230 forAll (curCell, faceI)
232 // Mark all the points as moving
233 const face& curFace = f[curCell[faceI]];
235 forAll (curFace, pointI)
237 movingPointsMask[curFace[pointI]] = 1;
242 // Attempt to enforce motion on sliders if zones exist
244 mesh_.faceZones().findZoneID(movingSliderName_ + "Zone" + name_);
248 const labelList& movingSliderAddr = mesh_.faceZones()[msI];
250 forAll (movingSliderAddr, faceI)
252 const face& curFace = f[movingSliderAddr[faceI]];
254 forAll (curFace, pointI)
256 movingPointsMask[curFace[pointI]] = 1;
262 mesh_.faceZones().findZoneID(staticSliderName_ + "Zone" + name_);
266 const labelList& staticSliderAddr = mesh_.faceZones()[ssI];
268 forAll (staticSliderAddr, faceI)
270 const face& curFace = f[staticSliderAddr[faceI]];
272 forAll (curFace, pointI)
274 movingPointsMask[curFace[pointI]] = 0;
281 // Return moving points mask. Moving points marked with 1
282 const Foam::scalarField& Foam::mixerRotor::movingPointsMask() const
284 if (!movingPointsMaskPtr_)
289 return *movingPointsMaskPtr_;
293 void Foam::mixerRotor::clearPointMask()
295 deleteDemandDrivenData(movingPointsMaskPtr_);
299 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
301 Foam::mixerRotor::mixerRotor
304 const polyMesh& mesh,
305 const dictionary& dict
313 dict.subDict("coordinateSystem")
315 rpm_(readScalar(dict.lookup("rpm"))),
316 movingSliderName_(dict.lookup("movingPatch")),
317 staticSliderName_(dict.lookup("staticPatch")),
318 rotatingRegionMarker_
320 dict.lookupOrDefault<point>("rotatingRegionMarker", cs_.origin())
324 dict.lookupOrDefault<bool>("invertMotionMask", false)
326 useTopoSliding_(dict.lookup("useTopoSliding")),
327 attachDetach_(dict.lookupOrDefault<bool>("attachDetach", true)),
328 movingPointsMaskPtr_(NULL)
330 // Make sure the coordinate system does not operate in degrees
331 // Bug fix, HJ, 3/Oct/2011
332 if (!cs_.inDegrees())
336 "mixerRotor::mixerRotor\n"
338 " const word& name,\n"
339 " const polyMesh& mesh,\n"
340 " const dictionary& dict\n"
342 ) << "Mixer coordinate system is set to operate in radians. "
343 << "Changing to rad for correct calculation of angular velocity."
345 << "To remove this message please add entry" << nl << nl
346 << "inDegrees true;" << nl << nl
347 << "to the specification of the coordinate system"
350 cs_.inDegrees() = true;
353 Info<< "Rotor " << name << ":" << nl
354 << " origin : " << cs().origin() << nl
355 << " axis : " << cs().axis() << nl
356 << " rpm : " << rpm_ << nl
357 << " invert mask : " << invertMotionMask_ << nl
358 << " topo sliding: " << useTopoSliding_ << endl;
362 Info<< " attach-detach: " << attachDetach_ << endl;
367 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
369 Foam::mixerRotor::~mixerRotor()
375 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
377 Foam::tmp<Foam::vectorField> Foam::mixerRotor::pointMotion() const
379 // Rotational speed needs to be converted from rpm
380 scalarField mpm = movingPointsMask();
382 if (invertMotionMask_)
384 Info << "Inverting motion mask" << endl;
388 return cs_.globalPosition
390 // Motion vector in cylindrical coordinate system (x theta z)
391 cs_.localPosition(mesh_.allPoints())
392 + vector(0, rpm_*360.0*mesh_.time().deltaT().value()/60.0, 0)*mpm
393 ) - mesh_.allPoints();
397 void Foam::mixerRotor::updateTopology()
403 // ************************************************************************* //