1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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 \*---------------------------------------------------------------------------*/
28 #include "volFields.H"
29 #include "surfaceFields.H"
30 #include "slicedVolFields.H"
31 #include "slicedSurfaceFields.H"
33 #include "demandDrivenData.H"
34 #include "fvMeshLduAddressing.H"
35 #include "emptyPolyPatch.H"
36 #include "mapPolyMesh.H"
37 #include "MapFvFields.H"
38 #include "fvMeshMapper.H"
39 #include "mapClouds.H"
41 #include "volPointInterpolation.H"
42 #include "extendedLeastSquaresVectors.H"
43 #include "extendedLeastSquaresVectors.H"
44 #include "leastSquaresVectors.H"
45 #include "CentredFitData.H"
46 #include "linearFitPolynomial.H"
47 #include "quadraticFitPolynomial.H"
48 #include "quadraticLinearFitPolynomial.H"
49 //#include "quadraticFitSnGradData.H"
50 #include "skewCorrectionVectors.H"
53 #include "centredCECCellToFaceStencilObject.H"
54 #include "centredCFCCellToFaceStencilObject.H"
55 #include "centredCPCCellToFaceStencilObject.H"
56 #include "centredFECCellToFaceStencilObject.H"
57 #include "upwindCECCellToFaceStencilObject.H"
58 #include "upwindCFCCellToFaceStencilObject.H"
59 #include "upwindCPCCellToFaceStencilObject.H"
60 #include "upwindFECCellToFaceStencilObject.H"
62 #include "centredCFCFaceToCellStencilObject.H"
64 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
66 defineTypeNameAndDebug(Foam::fvMesh, 0);
68 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
70 void Foam::fvMesh::clearGeomNotOldVol()
72 slicedVolScalarField::DimensionedInternalField* VPtr =
73 static_cast<slicedVolScalarField::DimensionedInternalField*>(VPtr_);
74 deleteDemandDrivenData(VPtr);
77 deleteDemandDrivenData(SfPtr_);
78 deleteDemandDrivenData(magSfPtr_);
79 deleteDemandDrivenData(CPtr_);
80 deleteDemandDrivenData(CfPtr_);
84 void Foam::fvMesh::clearGeom()
88 deleteDemandDrivenData(V0Ptr_);
89 deleteDemandDrivenData(V00Ptr_);
91 // Mesh motion flux cannot be deleted here because the old-time flux
94 // Things geometry dependent that are not updated.
95 volPointInterpolation::Delete(*this);
96 extendedLeastSquaresVectors::Delete(*this);
97 leastSquaresVectors::Delete(*this);
98 CentredFitData<linearFitPolynomial>::Delete(*this);
99 CentredFitData<quadraticFitPolynomial>::Delete(*this);
100 CentredFitData<quadraticLinearFitPolynomial>::Delete(*this);
101 skewCorrectionVectors::Delete(*this);
102 //quadraticFitSnGradData::Delete(*this);
106 void Foam::fvMesh::clearAddressing()
108 deleteDemandDrivenData(lduPtr_);
110 // Hack until proper callbacks. Below are all the fvMesh-MeshObjects.
112 volPointInterpolation::Delete(*this);
113 extendedLeastSquaresVectors::Delete(*this);
114 leastSquaresVectors::Delete(*this);
115 CentredFitData<linearFitPolynomial>::Delete(*this);
116 CentredFitData<quadraticFitPolynomial>::Delete(*this);
117 CentredFitData<quadraticLinearFitPolynomial>::Delete(*this);
118 skewCorrectionVectors::Delete(*this);
119 //quadraticFitSnGradData::Delete(*this);
121 centredCECCellToFaceStencilObject::Delete(*this);
122 centredCFCCellToFaceStencilObject::Delete(*this);
123 centredCPCCellToFaceStencilObject::Delete(*this);
124 centredFECCellToFaceStencilObject::Delete(*this);
125 // Is this geometry related - cells distorting to upwind direction?
126 upwindCECCellToFaceStencilObject::Delete(*this);
127 upwindCFCCellToFaceStencilObject::Delete(*this);
128 upwindCPCCellToFaceStencilObject::Delete(*this);
129 upwindFECCellToFaceStencilObject::Delete(*this);
131 centredCFCFaceToCellStencilObject::Delete(*this);
135 void Foam::fvMesh::clearOut()
138 surfaceInterpolation::clearOut();
142 // Clear mesh motion flux
143 deleteDemandDrivenData(phiPtr_);
145 polyMesh::clearOut();
149 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
151 Foam::fvMesh::fvMesh(const IOobject& io)
154 surfaceInterpolation(*this),
155 boundary_(*this, boundaryMesh()),
157 curTimeIndex_(time().timeIndex()),
169 Info<< "Constructing fvMesh from IOobject"
173 // Check the existance of the cell volumes and read if present
174 // and set the storage of V00
175 if (isFile(time().timePath()/"V0"))
177 V0Ptr_ = new DimensionedField<scalar, volMesh>
193 // Check the existance of the mesh fluxes, read if present and set the
195 if (isFile(time().timePath()/"meshPhi"))
197 phiPtr_ = new surfaceScalarField
210 // The mesh is now considered moving so the old-time cell volumes
211 // will be required for the time derivatives so if they haven't been
212 // read initialise to the current cell volumes
215 V0Ptr_ = new DimensionedField<scalar, volMesh>
238 const Xfer<pointField>& points,
239 const Xfer<faceList>& faces,
240 const Xfer<labelList>& allOwner,
241 const Xfer<labelList>& allNeighbour,
245 polyMesh(io, points, faces, allOwner, allNeighbour, syncPar),
246 surfaceInterpolation(*this),
249 curTimeIndex_(time().timeIndex()),
261 Info<< "Constructing fvMesh from components" << endl;
269 const Xfer<pointField>& points,
270 const Xfer<faceList>& faces,
271 const Xfer<cellList>& cells,
275 polyMesh(io, points, faces, cells, syncPar),
276 surfaceInterpolation(*this),
279 curTimeIndex_(time().timeIndex()),
291 Info<< "Constructing fvMesh from components" << endl;
296 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
298 Foam::fvMesh::~fvMesh()
304 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
306 void Foam::fvMesh::addFvPatches
308 const List<polyPatch*> & p,
309 const bool validBoundary
312 if (boundary().size())
316 "fvMesh::addFvPatches(const List<polyPatch*>&, const bool)"
317 ) << " boundary already exists"
318 << abort(FatalError);
321 // first add polyPatches
322 addPatches(p, validBoundary);
323 boundary_.addPatches(boundaryMesh());
327 void Foam::fvMesh::removeFvBoundary()
331 Info<< "void fvMesh::removeFvBoundary(): "
332 << "Removing boundary patches."
336 // Remove fvBoundaryMesh data first.
338 boundary_.setSize(0);
339 polyMesh::removeBoundary();
345 Foam::polyMesh::readUpdateState Foam::fvMesh::readUpdate()
349 Info<< "polyMesh::readUpdateState fvMesh::readUpdate() : "
350 << "Updating fvMesh. ";
353 polyMesh::readUpdateState state = polyMesh::readUpdate();
355 if (state == polyMesh::TOPO_PATCH_CHANGE)
359 Info << "Boundary and topological update" << endl;
362 boundary_.readUpdate(boundaryMesh());
367 else if (state == polyMesh::TOPO_CHANGE)
371 Info << "Topological update" << endl;
376 else if (state == polyMesh::POINTS_MOVED)
380 Info << "Point motion update" << endl;
389 Info << "No update" << endl;
397 const Foam::fvBoundaryMesh& Foam::fvMesh::boundary() const
403 const Foam::lduAddressing& Foam::fvMesh::lduAddr() const
407 lduPtr_ = new fvMeshLduAddressing(*this);
414 void Foam::fvMesh::mapFields(const mapPolyMesh& meshMap)
417 const fvMeshMapper mapper(*this, meshMap);
419 // Map all the volFields in the objectRegistry
420 MapGeometricFields<scalar, fvPatchField, fvMeshMapper, volMesh>
422 MapGeometricFields<vector, fvPatchField, fvMeshMapper, volMesh>
424 MapGeometricFields<sphericalTensor, fvPatchField, fvMeshMapper, volMesh>
426 MapGeometricFields<symmTensor, fvPatchField, fvMeshMapper, volMesh>
428 MapGeometricFields<tensor, fvPatchField, fvMeshMapper, volMesh>
431 // Map all the surfaceFields in the objectRegistry
432 MapGeometricFields<scalar, fvsPatchField, fvMeshMapper, surfaceMesh>
434 MapGeometricFields<vector, fvsPatchField, fvMeshMapper, surfaceMesh>
436 MapGeometricFields<symmTensor, fvsPatchField, fvMeshMapper, surfaceMesh>
438 MapGeometricFields<symmTensor, fvsPatchField, fvMeshMapper, surfaceMesh>
440 MapGeometricFields<tensor, fvsPatchField, fvMeshMapper, surfaceMesh>
443 // Map all the clouds in the objectRegistry
444 mapClouds(*this, meshMap);
447 const labelList& cellMap = meshMap.cellMap();
449 // Map the old volume. Just map to new cell labels.
452 scalarField& V0 = *V0Ptr_;
454 scalarField savedV0(V0);
455 V0.setSize(nCells());
461 V0[i] = savedV0[cellMap[i]];
470 // Map the old-old volume. Just map to new cell labels.
473 scalarField& V00 = *V00Ptr_;
475 scalarField savedV00(V00);
476 V00.setSize(nCells());
482 V00[i] = savedV00[cellMap[i]];
493 // Temporary helper function to call move points on
496 void MeshObjectMovePoints(const Foam::fvMesh& mesh)
498 if (mesh.thisDb().foundObject<Type>(Type::typeName))
502 mesh.thisDb().lookupObject<Type>
511 Foam::tmp<Foam::scalarField> Foam::fvMesh::movePoints(const pointField& p)
513 // Grab old time volumes if the time has been incremented
514 if (curTimeIndex_ < time().timeIndex())
516 if (V00Ptr_ && V0Ptr_)
527 V0Ptr_ = new DimensionedField<scalar, volMesh>
541 curTimeIndex_ = time().timeIndex();
545 // delete out of date geometrical information
546 clearGeomNotOldVol();
551 // Create mesh motion flux
552 phiPtr_ = new surfaceScalarField
557 this->time().timeName(),
568 // Grab old time mesh motion fluxes if the time has been incremented
569 if (phiPtr_->timeIndex() != time().timeIndex())
575 surfaceScalarField& phi = *phiPtr_;
577 // Move the polyMesh and set the mesh motion fluxes to the swept-volumes
579 scalar rDeltaT = 1.0/time().deltaT().value();
581 tmp<scalarField> tsweptVols = polyMesh::movePoints(p);
582 scalarField& sweptVols = tsweptVols();
584 phi.internalField() = scalarField::subField(sweptVols, nInternalFaces());
585 phi.internalField() *= rDeltaT;
587 const fvPatchList& patches = boundary();
589 forAll (patches, patchI)
591 phi.boundaryField()[patchI] = patches[patchI].patchSlice(sweptVols);
592 phi.boundaryField()[patchI] *= rDeltaT;
595 boundary_.movePoints();
596 surfaceInterpolation::movePoints();
599 // Hack until proper callbacks. Below are all the fvMesh MeshObjects with a
600 // movePoints function.
601 MeshObjectMovePoints<volPointInterpolation>(*this);
602 MeshObjectMovePoints<extendedLeastSquaresVectors>(*this);
603 MeshObjectMovePoints<leastSquaresVectors>(*this);
604 MeshObjectMovePoints<CentredFitData<linearFitPolynomial> >(*this);
605 MeshObjectMovePoints<CentredFitData<quadraticFitPolynomial> >(*this);
606 MeshObjectMovePoints<CentredFitData<quadraticLinearFitPolynomial> >(*this);
607 MeshObjectMovePoints<skewCorrectionVectors>(*this);
608 //MeshObjectMovePoints<quadraticFitSnGradData>(*this);
614 void Foam::fvMesh::updateMesh(const mapPolyMesh& mpm)
616 // Update polyMesh. This needs to keep volume existent!
617 polyMesh::updateMesh(mpm);
619 // Clear the sliced fields
620 clearGeomNotOldVol();
622 // Map all fields using current (i.e. not yet mapped) volume
625 // Clear the current volume and other geometry factors
626 surfaceInterpolation::clearOut();
630 // handleMorph() should also clear out the surfaceInterpolation.
631 // This is a temporary solution
632 surfaceInterpolation::movePoints();
636 bool Foam::fvMesh::writeObjects
638 IOstream::streamFormat fmt,
639 IOstream::versionNumber ver,
640 IOstream::compressionType cmp
643 return polyMesh::writeObject(fmt, ver, cmp);
647 //- Write mesh using IO settings from the time
648 bool Foam::fvMesh::write() const
650 return polyMesh::write();
654 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
656 bool Foam::fvMesh::operator!=(const fvMesh& bm) const
662 bool Foam::fvMesh::operator==(const fvMesh& bm) const
668 // ************************************************************************* //