Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / finiteVolume / fvMesh / fvMesh.C
blobc422c8128d30d40c106012b1a3dc70319964125a
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 "fvMesh.H"
27 #include "volFields.H"
28 #include "surfaceFields.H"
29 #include "slicedVolFields.H"
30 #include "slicedSurfaceFields.H"
31 #include "SubField.H"
32 #include "demandDrivenData.H"
33 #include "fvMeshLduAddressing.H"
34 #include "emptyPolyPatch.H"
35 #include "mapPolyMesh.H"
36 #include "MapFvFields.H"
37 #include "fvMeshMapper.H"
38 #include "mapClouds.H"
40 #include "volPointInterpolation.H"
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 defineTypeNameAndDebug(Foam::fvMesh, 0);
47 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
49 void Foam::fvMesh::clearGeomNotOldVol()
51     deleteDemandDrivenData(VPtr_);
53     deleteDemandDrivenData(SfPtr_);
54     deleteDemandDrivenData(magSfPtr_);
55     deleteDemandDrivenData(CPtr_);
56     deleteDemandDrivenData(CfPtr_);
60 void Foam::fvMesh::clearGeom()
62     clearGeomNotOldVol();
64     deleteDemandDrivenData(V0Ptr_);
65     deleteDemandDrivenData(V00Ptr_);
67     // Mesh motion flux cannot be deleted here because the old-time flux
68     // needs to be saved.
70     // Geometry dependent object updated through call-back
71     // and handled by polyMesh
72     // HJ, 29/Aug/2010
76 void Foam::fvMesh::clearAddressing()
78     deleteDemandDrivenData(lduPtr_);
80     // Geometry dependent object updated through call-back
81     // and handled by polyMesh
82     // HJ, 29/Aug/2010
86 void Foam::fvMesh::clearOut()
88     clearGeom();
89     surfaceInterpolation::clearOut();
91     clearAddressing();
93     // Clear mesh motion flux
94     deleteDemandDrivenData(phiPtr_);
96     polyMesh::clearOut();
100 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
102 Foam::fvMesh::fvMesh(const IOobject& io)
104     polyMesh(io),
105     surfaceInterpolation(*this),
106     boundary_(*this, boundaryMesh()),
107     lduPtr_(NULL),
108     curTimeIndex_(time().timeIndex()),
109     VPtr_(NULL),
110     V0Ptr_(NULL),
111     V00Ptr_(NULL),
112     SfPtr_(NULL),
113     magSfPtr_(NULL),
114     CPtr_(NULL),
115     CfPtr_(NULL),
116     phiPtr_(NULL)
118     if (debug)
119     {
120         Info<< "Constructing fvMesh from IOobject"
121             << endl;
122     }
124     // Check the existance of the cell volumes and read if present
125     // and set the storage of V00
126     if (isFile(time().timePath()/"V0"))
127     {
128         if (debug)
129         {
130             Info<< "Reading old cell volumes" << endl;
131         }
133         V0Ptr_ = new DimensionedField<scalar, volMesh>
134         (
135             IOobject
136             (
137                 "V0",
138                 time().timeName(),
139                 *this,
140                 IOobject::MUST_READ,
141                 IOobject::NO_WRITE
142             ),
143             *this
144         );
146         V00();
147     }
149     // Check the existance of the mesh fluxes, read if present and set the
150     // mesh to be moving
151     if (isFile(time().timePath()/"meshPhi"))
152     {
153         if (debug)
154         {
155             Info<< "Reading motion fluxes" << endl;
156         }
158         phiPtr_ = new surfaceScalarField
159         (
160             IOobject
161             (
162                 "meshPhi",
163                 time().timeName(),
164                 *this,
165                 IOobject::MUST_READ,
166                 IOobject::AUTO_WRITE
167             ),
168             *this
169         );
171         // The mesh is now considered moving so the old-time cell volumes
172         // will be required for the time derivatives so if they haven't been
173         // read initialise to the current cell volumes
174         if (!V0Ptr_)
175         {
176             V0Ptr_ = new DimensionedField<scalar, volMesh>
177             (
178                 IOobject
179                 (
180                     "V0",
181                     time().timeName(),
182                     *this,
183                     IOobject::NO_READ,
184                     IOobject::NO_WRITE,
185                     false
186                 ),
187                 V()
188             );
189         }
191         moving(true);
192     }
196 Foam::fvMesh::fvMesh
198     const IOobject& io,
199     const Xfer<pointField>& points,
200     const Xfer<faceList>& faces,
201     const Xfer<labelList>& allOwner,
202     const Xfer<labelList>& allNeighbour,
203     const bool syncPar
206     polyMesh(io, points, faces, allOwner, allNeighbour, syncPar),
207     surfaceInterpolation(*this),
208     boundary_(*this),
209     lduPtr_(NULL),
210     curTimeIndex_(time().timeIndex()),
211     VPtr_(NULL),
212     V0Ptr_(NULL),
213     V00Ptr_(NULL),
214     SfPtr_(NULL),
215     magSfPtr_(NULL),
216     CPtr_(NULL),
217     CfPtr_(NULL),
218     phiPtr_(NULL)
220     if (debug)
221     {
222         Info<< "Constructing fvMesh from components" << endl;
223     }
227 Foam::fvMesh::fvMesh
229     const IOobject& io,
230     const Xfer<pointField>& points,
231     const Xfer<faceList>& faces,
232     const Xfer<cellList>& cells,
233     const bool syncPar
236     polyMesh(io, points, faces, cells, syncPar),
237     surfaceInterpolation(*this),
238     boundary_(*this),
239     lduPtr_(NULL),
240     curTimeIndex_(time().timeIndex()),
241     VPtr_(NULL),
242     V0Ptr_(NULL),
243     V00Ptr_(NULL),
244     SfPtr_(NULL),
245     magSfPtr_(NULL),
246     CPtr_(NULL),
247     CfPtr_(NULL),
248     phiPtr_(NULL)
250     if (debug)
251     {
252         Info<< "Constructing fvMesh from components" << endl;
253     }
257 Foam::fvMesh::fvMesh
259     const IOobject& io,
260     const Xfer<pointField>& points,
261     const cellShapeList& shapes,
262     const faceListList& boundaryFaces,
263     const wordList& boundaryPatchNames,
264     const wordList& boundaryPatchTypes,
265     const word& defaultBoundaryPatchName,
266     const word& defaultBoundaryPatchType,
267     const wordList& boundaryPatchPhysicalTypes,
268     const bool syncPar
271     polyMesh
272     (
273         io,
274         points,
275         shapes,
276         boundaryFaces,
277         boundaryPatchNames,
278         boundaryPatchTypes,
279         defaultBoundaryPatchName,
280         defaultBoundaryPatchType,
281         boundaryPatchPhysicalTypes,
282         syncPar
283     ),
284     surfaceInterpolation(*this),
285     boundary_(*this),
286     lduPtr_(NULL),
287     curTimeIndex_(time().timeIndex()),
288     VPtr_(NULL),
289     V0Ptr_(NULL),
290     V00Ptr_(NULL),
291     SfPtr_(NULL),
292     magSfPtr_(NULL),
293     CPtr_(NULL),
294     CfPtr_(NULL),
295     phiPtr_(NULL)
297     if (debug)
298     {
299         Info<< "Constructing fvMesh from components" << endl;
300     }
304 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
306 Foam::fvMesh::~fvMesh()
308     clearOut();
312 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
314 void Foam::fvMesh::addFvPatches
316     const List<polyPatch*> & p,
317     const bool validBoundary
320     if (boundary().size())
321     {
322         FatalErrorIn
323         (
324             "fvMesh::addFvPatches(const List<polyPatch*>&, const bool)"
325         )   << " boundary already exists"
326             << abort(FatalError);
327     }
329     // first add polyPatches
330     addPatches(p, validBoundary);
331     boundary_.addPatches(boundaryMesh());
335 void Foam::fvMesh::removeFvBoundary()
337     if (debug)
338     {
339         Info<< "void fvMesh::removeFvBoundary(): "
340             << "Removing boundary patches."
341             << endl;
342     }
344     // Remove fvBoundaryMesh data first.
345     boundary_.clear();
346     boundary_.setSize(0);
347     polyMesh::removeBoundary();
349     clearOut();
353 Foam::polyMesh::readUpdateState Foam::fvMesh::readUpdate()
355     if (debug)
356     {
357         Info<< "polyMesh::readUpdateState fvMesh::readUpdate() : "
358             << "Updating fvMesh.  ";
359     }
361     // Note: issues with update: should meshObject update happen
362     // in polyMesh or fvMesh?  HJ, 18/Feb/2011
363     polyMesh::readUpdateState state = polyMesh::readUpdate();
365     if (state == polyMesh::TOPO_PATCH_CHANGE)
366     {
367         if (debug)
368         {
369             Info << "Boundary and topological update" << endl;
370         }
372         boundary_.readUpdate(boundaryMesh());
374         clearOut();
376     }
377     else if (state == polyMesh::TOPO_CHANGE)
378     {
379         if (debug)
380         {
381             Info << "Topological update" << endl;
382         }
384         clearOut();
385     }
386     else if (state == polyMesh::POINTS_MOVED)
387     {
388         if (debug)
389         {
390             Info << "Point motion update" << endl;
391         }
393         clearGeom();
394     }
395     else
396     {
397         if (debug)
398         {
399             Info << "No update" << endl;
400         }
401     }
403     return state;
407 const Foam::fvBoundaryMesh& Foam::fvMesh::boundary() const
409     return boundary_;
413 const Foam::lduAddressing& Foam::fvMesh::lduAddr() const
415     if (!lduPtr_)
416     {
417         lduPtr_ = new fvMeshLduAddressing(*this);
418     }
420     return *lduPtr_;
424 void Foam::fvMesh::mapFields(const mapPolyMesh& meshMap) const
426     if (debug)
427     {
428         Info<< "void fvMesh::mapFields(const mapPolyMesh& meshMap) const: "
429             << "Mapping fv fields."
430             << endl;
431     }
433     // Create a mapper
434     const fvMeshMapper mapper(*this, meshMap);
436     // Map all the volFields in the objectRegistry
437     MapGeometricFields<scalar, fvPatchField, fvMeshMapper, volMesh>(mapper);
438     MapGeometricFields<vector, fvPatchField, fvMeshMapper, volMesh>(mapper);
439     MapGeometricFields<sphericalTensor, fvPatchField, fvMeshMapper, volMesh>
440         (mapper);
442     MapGeometricFields<symmTensor, fvPatchField, fvMeshMapper, volMesh>
443         (mapper);
445     MapGeometricFields<symmTensor4thOrder, fvPatchField, fvMeshMapper, volMesh>
446       (mapper);
448     MapGeometricFields<diagTensor, fvPatchField, fvMeshMapper, volMesh>
449       (mapper);
451     MapGeometricFields<tensor, fvPatchField, fvMeshMapper, volMesh>(mapper);
453     // Map all the surfaceFields in the objectRegistry
454     MapGeometricFields<scalar, fvsPatchField, fvMeshMapper, surfaceMesh>
455         (mapper);
457     MapGeometricFields<vector, fvsPatchField, fvMeshMapper, surfaceMesh>
458         (mapper);
460     MapGeometricFields
461         <sphericalTensor, fvsPatchField, fvMeshMapper, surfaceMesh>(mapper);
462     MapGeometricFields<symmTensor, fvsPatchField, fvMeshMapper, surfaceMesh>
463         (mapper);
465     MapGeometricFields<symmTensor4thOrder, fvsPatchField, fvMeshMapper, surfaceMesh>
466       (mapper);
468     MapGeometricFields<diagTensor, fvsPatchField, fvMeshMapper, surfaceMesh>
469       (mapper);
471     MapGeometricFields<tensor, fvsPatchField, fvMeshMapper, surfaceMesh>
472         (mapper);
474     // Map all the clouds in the objectRegistry
475     mapClouds(*this, meshMap);
479 void Foam::fvMesh::mapOldVolumes(const mapPolyMesh& meshMap)
481     const labelList& cellMap = meshMap.cellMap();
483     // Map the old volume. Just map to new cell labels.
484     if (V0Ptr_)
485     {
486         if (debug)
487         {
488             InfoIn("void fvMesh::mapOldVolumes(const mapPolyMesh& meshMap)")
489                 << "Mapping old cell volumes." << endl;
490         }
492         scalarField& V0 = *V0Ptr_;
494         scalarField savedV0(V0);
495         V0.setSize(nCells());
497         forAll (V0, i)
498         {
499             if (cellMap[i] > -1)
500             {
501                 V0[i] = savedV0[cellMap[i]];
502             }
503             else
504             {
505                 V0[i] = 0.0;
506             }
507         }
508     }
510     // Map the old-old volume. Just map to new cell labels.
511     if (V00Ptr_)
512     {
513         if (debug)
514         {
515             InfoIn("void fvMesh::mapOldVolumes(const mapPolyMesh& meshMap)")
516                 << "Mapping old-old cell volumes." << endl;
517         }
519         scalarField& V00 = *V00Ptr_;
521         scalarField savedV00(V00);
522         V00.setSize(nCells());
524         forAll (V00, i)
525         {
526             if (cellMap[i] > -1)
527             {
528                 V00[i] = savedV00[cellMap[i]];
529             }
530             else
531             {
532                 V00[i] = 0.0;
533             }
534         }
535     }
539 void Foam::fvMesh::updateMesh(const mapPolyMesh& mpm)
541     // Update polyMesh. This needs to keep volume existent!
542     polyMesh::updateMesh(mpm);
544     surfaceInterpolation::clearOut();
545     clearGeomNotOldVol();
547     // Map all fields
548     mapFields(mpm);
550     // Map old-volumes
551     mapOldVolumes(mpm);
553     clearAddressing();
555     // Mesh morphing should also clear out the surfaceInterpolation.
556     // This is a temporary solution
557     surfaceInterpolation::movePoints();
559     // Function object update moved to polyMesh
560     // HJ, 29/Aug/2010
564 void Foam::fvMesh::syncUpdateMesh()
566     // Update polyMesh. This needs to keep volume existent!
567     polyMesh::syncUpdateMesh();
569     // Not sure how much clean-up is needed here.  HJ, 27/Nov/2009
571     surfaceInterpolation::clearOut();
572     clearGeomNotOldVol();
574     clearAddressing();
576     // handleMorph() should also clear out the surfaceInterpolation.
577     // This is a temporary solution
578     surfaceInterpolation::movePoints();
580     // Function object update moved to polyMesh
581     // HJ, 29/Aug/2010
585 Foam::tmp<Foam::scalarField> Foam::fvMesh::movePoints(const pointField& p)
587     // Grab old time volumes if the time has been incremented
588     if (curTimeIndex_ < time().timeIndex())
589     {
590         if (V00Ptr_ && V0Ptr_)
591         {
592             if (debug)
593             {
594                 InfoIn("void fvMesh::movePoints(const pointField& p)")
595                     << "Grabbing old-old cell volumes." << endl;
596             }
598             *V00Ptr_ = *V0Ptr_;
599         }
601         if (V0Ptr_)
602         {
603             if (debug)
604             {
605                 InfoIn("void fvMesh::movePoints(const pointField& p)")
606                     << "Grabbing old cell volumes." << endl;
607             }
609             *V0Ptr_ = V();
610         }
611         else
612         {
613             if (debug)
614             {
615                 InfoIn("void fvMesh::movePoints(const pointField& p)")
616                     << "Creating old cell volumes." << endl;
617             }
619             V0Ptr_ = new DimensionedField<scalar, volMesh>
620             (
621                 IOobject
622                 (
623                     "V0",
624                     time().timeName(),
625                     *this,
626                     IOobject::NO_READ,
627                     IOobject::NO_WRITE
628                 ),
629                 V()
630             );
631         }
633         curTimeIndex_ = time().timeIndex();
634     }
637     // Delete out of date geometrical information
638     clearGeomNotOldVol();
641     if (!phiPtr_)
642     {
643         // Create mesh motion flux
644         if (debug)
645         {
646             InfoIn("tmp<scalarField> fvMesh::movePoints(const pointField& p)")
647                 << "Creating new mesh motion fluxes" << endl;
648         }
650         phiPtr_ = new surfaceScalarField
651         (
652             IOobject
653             (
654                 "meshPhi",
655                 this->time().timeName(),
656                 *this,
657                 IOobject::NO_READ,
658                 IOobject::AUTO_WRITE
659             ),
660             *this,
661             dimVolume/dimTime
662         );
663     }
664     else
665     {
666         // Grab old time mesh motion fluxes if the time has been incremented
667         if (phiPtr_->timeIndex() < time().timeIndex())
668         {
669             phiPtr_->oldTime();
670         }
671     }
673     // Move the polyMesh and set the mesh motion fluxes to the swept-volumes
674     tmp<scalarField> tsweptVols = polyMesh::movePoints(p);
676     updatePhi(tsweptVols());
678     boundary_.movePoints();
679     surfaceInterpolation::movePoints();
681     // Function object update moved to polyMesh
682     // HJ, 29/Aug/2010
684     return tsweptVols;
688 bool Foam::fvMesh::writeObjects
690     IOstream::streamFormat fmt,
691     IOstream::versionNumber ver,
692     IOstream::compressionType cmp
693 ) const
695     return polyMesh::writeObject(fmt, ver, cmp);
699 //- Write mesh using IO settings from the time
700 bool Foam::fvMesh::write() const
702     return polyMesh::write();
706 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
708 bool Foam::fvMesh::operator!=(const fvMesh& bm) const
710     return &bm != this;
714 bool Foam::fvMesh::operator==(const fvMesh& bm) const
716     return &bm == this;
720 // ************************************************************************* //