Forward compatibility: flex
[foam-extend-3.2.git] / src / dynamicMesh / topoChangerFvMesh / linearValveFvMesh / linearValveFvMesh.C
blobc3ae1e99a8c222f84e8705976b6d71e502ef4a58
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 "linearValveFvMesh.H"
27 #include "foamTime.H"
28 #include "slidingInterface.H"
29 #include "mapPolyMesh.H"
30 #include "polyTopoChange.H"
31 #include "volMesh.H"
32 #include "addToRunTimeSelectionTable.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 namespace Foam
38     defineTypeNameAndDebug(linearValveFvMesh, 0);
40     addToRunTimeSelectionTable(topoChangerFvMesh, linearValveFvMesh, IOobject);
44 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
46 void Foam::linearValveFvMesh::addZonesAndModifiers()
48     // Add zones and modifiers for motion action
50     if
51     (
52         pointZones().size() > 0
53      || faceZones().size() > 0
54      || cellZones().size() > 0
55     )
56     {
57         Info<< "void linearValveFvMesh::addZonesAndModifiers() : "
58             << "Zones and modifiers already present.  Skipping."
59             << endl;
61         if (topoChanger_.size() == 0)
62         {
63             FatalErrorIn
64             (
65                 "void linearValveFvMesh::addZonesAndModifiers()"
66             )   << "Mesh modifiers not read properly"
67                 << abort(FatalError);
68         }
70         return;
71     }
73     Info<< "Time = " << time().timeName() << endl
74         << "Adding zones and modifiers to the mesh" << endl;
76     // Add zones
77     List<pointZone*> pz(1);
79     // Add an empty zone for cut points
81     pz[0] = new pointZone
82     (
83         "cutPointZone",
84         labelList(0),
85         0,
86         pointZones()
87     );
90     // Do face zones for slider
92     List<faceZone*> fz(3);
94     // Inner slider
95     const word innerSliderName(motionDict_.subDict("slider").lookup("inside"));
96     const polyPatch& innerSlider =
97         boundaryMesh()[boundaryMesh().findPatchID(innerSliderName)];
99     labelList isf(innerSlider.size());
101     forAll (isf, i)
102     {
103         isf[i] = innerSlider.start() + i;
104     }
106     fz[0] = new faceZone
107     (
108         "insideSliderZone",
109         isf,
110         boolList(innerSlider.size(), false),
111         0,
112         faceZones()
113     );
115     // Outer slider
116     const word outerSliderName(motionDict_.subDict("slider").lookup("outside"));
117     const polyPatch& outerSlider =
118         boundaryMesh()[boundaryMesh().findPatchID(outerSliderName)];
120     labelList osf(outerSlider.size());
122     forAll (osf, i)
123     {
124         osf[i] = outerSlider.start() + i;
125     }
127     fz[1] = new faceZone
128     (
129         "outsideSliderZone",
130         osf,
131         boolList(outerSlider.size(), false),
132         1,
133         faceZones()
134     );
136     // Add empty zone for cut faces
137     fz[2] = new faceZone
138     (
139         "cutFaceZone",
140         labelList(0),
141         boolList(0, false),
142         2,
143         faceZones()
144     );
146     List<cellZone*> cz(0);
148     Info << "Adding point, face and cell zones" << endl;
149     addZones(pz, fz, cz);
151     // Add a topology modifier
152     Info << "Adding topology modifiers" << endl;
153     topoChanger_.setSize(1);
154     topoChanger_.set
155     (
156         0,
157         new slidingInterface
158         (
159             "mixerSlider",
160             0,
161             topoChanger_,
162             outerSliderName + "Zone",
163             innerSliderName + "Zone",
164             "cutPointZone",
165             "cutFaceZone",
166             outerSliderName,
167             innerSliderName,
168             slidingInterface::INTEGRAL,   // Edge matching algorithm
169             true,                         // Attach-detach action
170             intersection::VISIBLE         // Projection algorithm
171         )
172     );
174     // Write mesh and modifiers
175     topoChanger_.writeOpt() = IOobject::AUTO_WRITE;
176     topoChanger_.write();
177     write();
181 void Foam::linearValveFvMesh::deactivateSliders()
183     const polyTopoChanger& topoChanges = topoChanger_;
185     // Enable layering
186     forAll (topoChanges, modI)
187     {
188         if (isA<slidingInterface>(topoChanges[modI]))
189         {
190             topoChanges[modI].disable();
191         }
192         else
193         {
194             FatalErrorIn("void Foam::linearValveFvMesh::deactivateSliders()")
195                 << "Don't know what to do with mesh modifier "
196                 << modI << " of type " << topoChanges[modI].type()
197                 << abort(FatalError);
198         }
199     }
203 void Foam::linearValveFvMesh::activateSliders()
205     const polyTopoChanger& topoChanges = topoChanger_;
207     // Enable sliding interface
208     forAll (topoChanges, modI)
209     {
210         if (isA<slidingInterface>(topoChanges[modI]))
211         {
212             topoChanges[modI].enable();
213         }
214         else
215         {
216             FatalErrorIn("void Foam::linearValveFvMesh::activateSliders()")
217                 << "Don't know what to do with mesh modifier "
218                 << modI << " of type " << topoChanges[modI].type()
219                 << abort(FatalError);
220         }
221     }
225 bool Foam::linearValveFvMesh::attached() const
227     const polyTopoChanger& topoChanges = topoChanger_;
229     bool result = false;
231     forAll (topoChanges, modI)
232     {
233         if (isA<slidingInterface>(topoChanges[modI]))
234         {
235             result =
236                 result
237              || refCast<const slidingInterface>(topoChanges[modI]).attached();
238         }
239     }
241     // Check thal all sliders are in sync (debug only)
242     forAll (topoChanges, modI)
243     {
244         if (isA<slidingInterface>(topoChanges[modI]))
245         {
246             if
247             (
248                 result
249              != refCast<const slidingInterface>(topoChanges[modI]).attached()
250             )
251             {
252                 FatalErrorIn("bool linearValveFvMesh::attached() const")
253                     << "Slider " << modI << " named "
254                     << topoChanges[modI].name()
255                     << " out of sync: Should be" << result
256                     << abort(FatalError);
257             }
258         }
259     }
261     if (result)
262     {
263         Info << "linearValveFvMesh: attached!" << endl;
264     }
265     else
266     {
267         Info << "linearValveFvMesh: detached!" << endl;
268     }
270     return result;
274 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
276 // Construct from components
277 Foam::linearValveFvMesh::linearValveFvMesh(const IOobject& io)
279     topoChangerFvMesh(io),
280     motionDict_
281     (
282         IOdictionary
283         (
284             IOobject
285             (
286                 "dynamicMeshDict",
287                 time().constant(),
288                 *this,
289                 IOobject::MUST_READ,
290                 IOobject::NO_WRITE
291             )
292         ).subDict(typeName + "Coeffs")
293     ),
294     msPtr_(motionSolver::New(*this))
296     addZonesAndModifiers();
300 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
302 Foam::linearValveFvMesh::~linearValveFvMesh()
306 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
308 bool Foam::linearValveFvMesh::update()
310     // Detaching the interface
311     if (attached())
312     {
313         Info << "Decoupling sliding interfaces" << endl;
314         activateSliders();
316         // Changing topology by hand
317         autoPtr<mapPolyMesh> topoChangeMap1 = topoChanger_.changeMesh();
319         if (topoChangeMap1->morphing())
320         {
321             msPtr_->updateMesh(topoChangeMap1());
322         }
323     }
324     else
325     {
326         Info << "Sliding interfaces decoupled" << endl;
327     }
329     // Perform mesh motion
330     deactivateSliders();
332     // Changing topology by hand
333     {
334         autoPtr<mapPolyMesh> topoChangeMap2 = topoChanger_.changeMesh();
336         if (topoChangeMap2->morphing())
337         {
338             msPtr_->updateMesh(topoChangeMap2());
340             if (topoChangeMap2->hasMotionPoints())
341             {
342                 Info << "Topology change; executing pre-motion" << endl;
343                 movePoints(topoChangeMap2->preMotionPoints());
344             }
345         }
346     }
348     // Solve for motion
349     msPtr_->solve();
351     movePoints(msPtr_->curPoints());
353     // Attach the interface
354     Info << "Coupling sliding interfaces" << endl;
355     activateSliders();
357     // Changing topology by hand
358     {
359         // Grab old points to correct the motion
360         pointField oldPointsNew = oldAllPoints();
362         autoPtr<mapPolyMesh> topoChangeMap3 = topoChanger_.changeMesh();
364         Info << "Moving points post slider attach" << endl;
366         bool localMorphing3 = topoChangeMap3->morphing();
367         bool globalMorphing3 = localMorphing3;
369         reduce(globalMorphing3, orOp<bool>());
371         if (globalMorphing3)
372         {
373             pointField newPoints = allPoints();
375             if (localMorphing3)
376             {
377                 msPtr_->updateMesh(topoChangeMap3());
379                 pointField mappedOldPointsNew(newPoints.size());
381                 mappedOldPointsNew.map
382                 (
383                     oldPointsNew,
384                     topoChangeMap3->pointMap()
385                 );
387                 // Solve the correct mesh motion to make sure motion fluxes
388                 // are solved for and not mapped
389                 // Note: using setOldPoints instead of movePoints.
390                 // HJ, 23/Aug/2015
391                 setOldPoints(mappedOldPointsNew);
393                 resetMotion();
394                 setV0();
396                 fvMesh::movePoints(newPoints);
397             }
398             else
399             {
400                 // No local topological change.  Execute double motion for
401                 // sync with topological changes
402                 // Note: using setOldPoints instead of movePoints.
403                 // HJ, 23/Aug/2015
404                 setOldPoints(oldPointsNew);
406                 resetMotion();
407                 setV0();
409                 // Set new point motion
410                 fvMesh::movePoints(newPoints);
411             }
412         }
413     }
415     Info << "Sliding interfaces coupled: " << attached() << endl;
417     return true;
421 // ************************************************************************* //