Forward compatibility: flex
[foam-extend-3.2.git] / src / dynamicMesh / topoChangerFvMesh / multiMixerFvMesh / multiMixerFvMesh.C
blobcd16d0d3c962ee594b27343eb2168f00b43c9686
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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 "multiMixerFvMesh.H"
27 #include "foamTime.H"
28 #include "regionSplit.H"
29 #include "slidingInterface.H"
30 #include "mapPolyMesh.H"
31 #include "volMesh.H"
32 #include "addToRunTimeSelectionTable.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 namespace Foam
38     defineTypeNameAndDebug(multiMixerFvMesh, 0);
39     addToRunTimeSelectionTable(topoChangerFvMesh, multiMixerFvMesh, IOobject);
43 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
45 void Foam::multiMixerFvMesh::addZonesAndModifiers()
47     // Add zones and modifiers for motion action
49     if
50     (
51         pointZones().size() > 0
52      || faceZones().size() > 0
53      || cellZones().size() > 0
54     )
55     {
56         Info<< "void multiMixerFvMesh::addZonesAndModifiers() : "
57             << "Zones and modifiers already present.  Skipping."
58             << endl;
60         if (topoChanger_.size() == 0  && useTopoSliding())
61         {
62             FatalErrorIn
63             (
64                 "void multiMixerFvMesh::addZonesAndModifiers()"
65             )   << "Mesh modifiers not read properly"
66                 << abort(FatalError);
67         }
69         return;
70     }
72     Info<< "Time = " << time().timeName() << endl
73         << "Adding zones and modifiers to the mesh.  " << rotors_.size()
74         << " sliders found" << endl;
76     DynamicList<pointZone*> pz(rotors_.size());
77     DynamicList<faceZone*> fz(3*rotors_.size());
78     DynamicList<cellZone*> cz(rotors_.size());
80     // Create region split: mark every cell with its topological region
81     regionSplit rs(*this);
83     Info << "Adding point, face and cell zones" << endl;
84     forAll (rotors_, rotorI)
85     {
86         rotors_[rotorI].addZones(pz, fz, cz, rs);
87     }
89     {
90         List<pointZone*> pzList;
91         pzList.transfer(pz.shrink());
93         List<faceZone*> fzList;
94         fzList.transfer(fz.shrink());
96         List<cellZone*> czList;
97         czList.transfer(cz.shrink());
99         addZones(pzList, fzList, czList);
100     }
102     if (useTopoSliding())
103     {
104         topoChanger_.setSize(rotors_.size());
105         label nextI = 0;
107         forAll (rotors_, rotorI)
108         {
109             rotors_[rotorI].addModifiers(topoChanger_, nextI);
110         }
112         Info<< "Adding topology modifiers.  nModifiers = " << nextI << endl;
114         // Resize and set topo changer
115         topoChanger_.setSize(nextI);
116         topoChanger_.writeOpt() = IOobject::AUTO_WRITE;
117         topoChanger_.write();
118     }
120     // Write mesh with new zones
121     write();
125 bool Foam::multiMixerFvMesh::useTopoSliding() const
127     bool result = false;
129     forAll (rotors_, rotorI)
130     {
131         result = (result || rotors_[rotorI].useTopoSliding());
132     }
134     return result;
138 void Foam::multiMixerFvMesh::checkRotors() const
140     // Check if all sliding interfaces are in the same state
141     bool rotorState = attached();
143     forAll (topoChanger_, topoI)
144     {
145         if (isA<slidingInterface>(topoChanger_[topoI]))
146         {
147             const slidingInterface& slider =
148                 refCast<const slidingInterface>(topoChanger_[topoI]);
150             if (rotorState != slider.attached())
151             {
152                 FatalErrorIn
153                 (
154                     "void multiMixerFvMesh::checkRotors() const"
155                 )   << "Some sliders are attached and some are not.  "
156                     << "Out of sync sliders cannot be handled."
157                     << abort(FatalError);
158             }
159         }
160     }
164 bool Foam::multiMixerFvMesh::attached() const
166     // Check if interfaces are attached AND if they are in sync
167     bool attached = false;
169     forAll (topoChanger_, topoI)
170     {
171         if (isA<slidingInterface>(topoChanger_[topoI]))
172         {
173             attached = attached
174                 || refCast<const slidingInterface>(topoChanger_[0]).attached();
175         }
176     }
178     return attached;
182 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
184 // Construct from components
185 Foam::multiMixerFvMesh::multiMixerFvMesh
187     const IOobject& io
190     topoChangerFvMesh(io),
191     dict_
192     (
193         IOdictionary
194         (
195             IOobject
196             (
197                 "dynamicMeshDict",
198                 time().constant(),
199                 *this,
200                 IOobject::MUST_READ,
201                 IOobject::NO_WRITE
202             )
203         ).subDict(typeName + "Coeffs")
204     ),
205     rotors_(),
206     attachDetach_(dict_.lookupOrDefault<bool>("attachDetach", true))
208     // Read rotors from the dictionary
209     PtrList<entry> rotorEntries(dict_.lookup("rotors"));
210     rotors_.setSize(rotorEntries.size());
212     forAll (rotorEntries, rotorI)
213     {
214         rotors_.set
215         (
216             rotorI,
217             new mixerRotor
218             (
219                 rotorEntries[rotorI].keyword(),
220                 *this,
221                 rotorEntries[rotorI].dict()
222             )
223         );
224     }
226     addZonesAndModifiers();
230 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
232 Foam::multiMixerFvMesh::~multiMixerFvMesh()
236 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
238 bool Foam::multiMixerFvMesh::update()
240     if (useTopoSliding())
241     {
242         // Detaching the interface
243         if (attached() && attachDetach_)
244         {
245             Info << "Detaching rotors" << endl;
246             autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
248             forAll (rotors_, rotorI)
249             {
250                 rotors_[rotorI].updateTopology();
251             }
252         }
253     }
255     // Accumulate point motion
256     vectorField pointMotion(allPoints().size(), vector::zero);
258     forAll (rotors_, rotorI)
259     {
260         pointMotion += rotors_[rotorI].pointMotion();
261     }
263     // Save old points
264     pointField oldPointsNew = allPoints();
266     // Move points
267     movePoints(allPoints() + pointMotion);
269     if (useTopoSliding())
270     {
271         autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
272         bool morphing = topoChangeMap.valid();
274         if (morphing)
275         {
276             Info << "Attaching rotors" << endl;
278             forAll (rotors_, rotorI)
279             {
280                 rotors_[rotorI].updateTopology();
281             }
283             // Move the sliding interface points to correct position
284             pointField mappedOldPointsNew(allPoints().size());
285             mappedOldPointsNew.map(oldPointsNew, topoChangeMap->pointMap());
287             // Note: using setOldPoints instead of movePoints.
288             // HJ, 23/Aug/2015
289             setOldPoints(mappedOldPointsNew);
291             resetMotion();
292             setV0();
294             // Move the sliding interface points to correct position
295             movePoints(topoChangeMap->preMotionPoints());
296         }
297     }
299     return true;
303 // ************************************************************************* //