Initial commit of NavalHydro package from Wikki to the ShipHydroSIG
[ShipHydroSIG.git] / src / vofDynamicMesh / lnInclude / sixDofTopoMotion.C
blob95d3f73ef138289629b302d7c423bfcd79bcc09b
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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 \*---------------------------------------------------------------------------*/
27 #include "sixDofTopoMotion.H"
28 #include "addToRunTimeSelectionTable.H"
29 #include "motionSolver.H"
30 #include "volFields.H"
31 #include "cellSet.H"
33 #include "tetFemMatrices.H"
34 #include "tetPointFields.H"
35 #include "faceTetPolyPatch.H"
36 #include "fixedValueTetPolyPatchFields.H"
38 #include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H"
40 #include "slidingInterface.H"
41 #include "mapPolyMesh.H"
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45 namespace Foam
47     defineTypeNameAndDebug(sixDofTopoMotion, 0);
49     addToRunTimeSelectionTable(dynamicFvMesh, sixDofTopoMotion, IOobject);
50 } // End namespace Foam
53 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
55 void Foam::sixDofTopoMotion::addZonesAndModifiers()
57     // Add zones and modifiers for motion action
59     if (useTopoSliding_)
60     {
61         if
62         (
63             pointZones().size() > 0
64          || faceZones().size() > 0
65          || cellZones().size() > 0
66         )
67         {
68             Info<< "void sixDofTopoMotion::addZonesAndModifiers() : "
69                 << "Zones and modifiers already present.  Skipping."
70                 << endl;
72             if (topoChanger_.size() == 0)
73             {
74                 FatalErrorIn
75                 (
76                     "void sixDofTopoMotion::addZonesAndModifiers()"
77                 )   << "Mesh modifiers not read properly"
78                     << abort(FatalError);
79             }
81             return;
82         }
84         Info<< "Time = " << time().timeName() << endl
85             << "Adding zones and modifiers to the mesh" << endl;
87         // Add zones
88         List<pointZone*> pz(3*bodies_.size());
89         List<faceZone*> fz(3*bodies_.size());
90         List<cellZone*> cz(0);
92         label npz = 0;
93         label nfz = 0;
94         label nSliders = 0;
96         forAll (bodies_, bodyI)
97         {
98             const floatingBody& curBody = bodies_[bodyI];
100             if
101             (
102                 curBody.hullSlider().active()
103              && curBody.fixedSlider().active()
104             )
105             {
106                 nSliders++;
108                 // Add an empty zone for cut points
109                 pz[npz] = new pointZone
110                 (
111                     curBody.name() + "CutPointZone",
112                     labelList(0),
113                     npz,
114                     pointZones()
115                 );
116                 npz++;
118                 // Do face zones for slider
120                 // Inner slider
121                 const polyPatch& innerSlider =
122                     boundaryMesh()[curBody.hullSlider().index()];
124                 labelList isf(innerSlider.size());
126                 forAll (isf, i)
127                 {
128                     isf[i] = innerSlider.start() + i;
129                 }
131                 fz[nfz] = new faceZone
132                 (
133                     curBody.name() + "InsideSliderZone",
134                     isf,
135                     boolList(innerSlider.size(), false),
136                     nfz,
137                     faceZones()
138                 );
139                 nfz++;
141                 // Outer slider
142                 const polyPatch& outerSlider =
143                     boundaryMesh()[curBody.fixedSlider().index()];
145                 labelList osf(outerSlider.size());
147                 forAll (osf, i)
148                 {
149                     osf[i] = outerSlider.start() + i;
150                 }
152                 fz[nfz] = new faceZone
153                 (
154                     curBody.name() + "OutsideSliderZone",
155                     osf,
156                     boolList(outerSlider.size(), false),
157                     nfz,
158                     faceZones()
159                 );
160                 nfz++;
162                 // Add empty zone for cut faces
163                 fz[nfz] = new faceZone
164                 (
165                     curBody.name() + "CutFaceZone",
166                     labelList(0),
167                     boolList(0, false),
168                     nfz,
169                     faceZones()
170                 );
171                 nfz++;
172             }
173         }
175         pz.setSize(npz);
176         fz.setSize(nfz);
179         Info << "Adding point and face zones" << endl;
180         addZones(pz, fz, cz);
182         // Add topology modifiers
183         topoChanger_.setSize(nSliders);
184         label nTopos = 0;
186         forAll (bodies_, bodyI)
187         {
188             const floatingBody& curBody = bodies_[bodyI];
190             if
191             (
192                 curBody.hullSlider().active()
193              && curBody.fixedSlider().active()
194             )
195             {
196                 topoChanger_.set
197                 (
198                     nTopos,
199                     new slidingInterface
200                     (
201                         curBody.name() + "Slider",
202                         nTopos,
203                         topoChanger_,
204                         curBody.name() + "OutsideSliderZone",
205                         curBody.name() + "InsideSliderZone",
206                         curBody.name() + "CutPointZone",
207                         curBody.name() + "CutFaceZone",
208                         curBody.fixedSlider().name(),
209                         curBody.hullSlider().name(),
210                         slidingInterface::INTEGRAL,   // Edge matching algorithm
211                         true,                         // Attach-detach action
212                         intersection::VISIBLE         // Projection algorithm
213                     )
214                 );
215             }
216         }
218         topoChanger_.writeOpt() = IOobject::AUTO_WRITE;
219         topoChanger_.write();
220         write();
221     }
222     else if (topoChanger_.size() > 0)
223     {
224         if (topoChanger_.size() != 0)
225         {
226             FatalErrorIn
227             (
228                 "void sixDofTopoMotion::addZonesAndModifiers()"
229             )   << "Mesh modifiers are present and topo sliding is set to off"
230                 << abort(FatalError);
231         }
232     }
236 bool Foam::sixDofTopoMotion::attached() const
238     const polyTopoChanger& topoChanges = topoChanger_;
240     bool result = false;
242     forAll (topoChanges, modI)
243     {
244         if (typeid(topoChanges[modI]) == typeid(slidingInterface))
245         {
246             result =
247                 result
248              || refCast<const slidingInterface>(topoChanges[modI]).attached();
249         }
250     }
252     return result;
256 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
258 Foam::sixDofTopoMotion::sixDofTopoMotion(const IOobject& io)
260     topoChangerFvMesh(io),
261     dict_
262     (
263         IOdictionary
264         (
265             IOobject
266             (
267                 "dynamicMeshDict",
268                 time().constant(),
269                 *this,
270                 IOobject::MUST_READ,
271                 IOobject::NO_WRITE
272             )
273         ).subDict(typeName + "Coeffs")
274     ),
275     bodies_(*this, dict_.lookup("bodies")),
276     useTopoSliding_(dict_.lookup("useTopoSliding")),
277     motionPtr_(motionSolver::New(*this))
279     addZonesAndModifiers();
283 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
285 Foam::sixDofTopoMotion::~sixDofTopoMotion()
289 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
291 bool Foam::sixDofTopoMotion::update()
293     // Detaching the interface
294     if (useTopoSliding_)
295     {
296         if (attached())
297         {
298             // Changing topology by hand
299             autoPtr<mapPolyMesh> topoChangeMap1 = topoChanger_.changeMesh();
301             if (topoChangeMap1.valid())
302             {
303                 Info << "Decoupling sliding interfaces" << endl;
304                 motionPtr_->updateMesh(topoChangeMap1());
305             }
306         }
307         else
308         {
309             Info << "Sliding interfaces decoupled" << endl;
310         }
311     }
313     // Set the motion onto the motion patch
314     tetPointVectorField& motionU =
315         const_cast<tetPointVectorField&>
316         (
317             this->objectRegistry::lookupObject<tetPointVectorField>("motionU")
318         );
320     // Set motion from bodies
321     bodies_.setMotion(motionU);
323     // Save old points
324     pointField oldPointsNew = allPoints();
326     // Calculate the motion and move points
327     movePoints(motionPtr_->newPoints());
329     // Attach the interface
330     // Changing topology by hand
331     if (useTopoSliding_)
332     {
333         autoPtr<mapPolyMesh> topoChangeMap2 = topoChanger_.changeMesh();
335         bool meshChanged2 = topoChangeMap2.valid();
337         if (meshChanged2)
338         {
339             Info << "Coupling sliding interfaces" << endl;
340             motionPtr_->updateMesh(topoChangeMap2());
342             if (debug)
343             {
344                 Info << "Moving points post slider attach" << endl;
345             }
347             pointField mappedOldPointsNew(allPoints().size());
348             mappedOldPointsNew.map(oldPointsNew, topoChangeMap2->pointMap());
350             movePoints(mappedOldPointsNew);
351             resetMotion();
352             setV0();
354             movePoints(topoChangeMap2->preMotionPoints());
355         }
357         // Topological change: return true
358         return true;
359     }
360     else
361     {
362         return false;
363     }
367 // ************************************************************************* //