1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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
27 \*---------------------------------------------------------------------------*/
30 #include "faGlobalMeshData.H"
33 #include "primitiveMesh.H"
34 #include "demandDrivenData.H"
35 #include "IndirectList.H"
36 #include "areaFields.H"
37 #include "edgeFields.H"
38 #include "faMeshLduAddressing.H"
39 #include "wedgeFaPatch.H"
40 #include "faPatchData.H"
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
46 defineTypeNameAndDebug(faMesh, 0);
49 Foam::word Foam::faMesh::meshSubDir = "faMesh";
51 const bool Foam::faMesh::quadricsFit_
53 debug::optimisationSwitch("quadricsFit", 0) > 0
56 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58 void Foam::faMesh::setPrimitiveMeshData()
62 Info<< "void faMesh::setPrimitiveMeshData() const : "
63 << "Setting primitive data" << endl;
66 const indirectPrimitivePatch& bp = patch();
69 edges_.setSize(bp.nEdges());
74 label nIntEdges = bp.nInternalEdges();
76 for (label curEdge = 0; curEdge < nIntEdges; curEdge++)
78 edges_[++edgeI] = bp.edges()[curEdge];
81 forAll (boundary(), patchI)
83 const faPatch& curP = boundary()[patchI];
87 edges_[++edgeI] = bp.edges()[curP[eI]];
91 nEdges_ = edges_.size();
92 nInternalEdges_ = nIntEdges;
95 // Set edge owner and neighbour
96 edgeOwner_.setSize(nEdges());
97 edgeNeighbour_.setSize(nInternalEdges());
101 const labelListList& bpef = bp.edgeFaces();
103 for (label curEdge = 0; curEdge < nIntEdges; curEdge++)
105 edgeOwner_[++edgeI] = bpef[curEdge][0];
107 edgeNeighbour_[edgeI] = bpef[curEdge][1];
110 forAll (boundary(), patchI)
112 const faPatch& curP = boundary()[patchI];
116 edgeOwner_[++edgeI] = bpef[curP[eI]][0];
120 // Set number of faces
123 // Set number of points
124 nPoints_ = bp.nPoints();
128 void Foam::faMesh::clearGeomNotAreas() const
132 Info<< "void faMesh::clearGeomNotAreas() const : "
133 << "Clearing geometry" << endl;
136 deleteDemandDrivenData(SPtr_);
137 deleteDemandDrivenData(patchPtr_);
138 deleteDemandDrivenData(patchStartsPtr_);
139 deleteDemandDrivenData(LePtr_);
140 deleteDemandDrivenData(magLePtr_);
141 deleteDemandDrivenData(centresPtr_);
142 deleteDemandDrivenData(edgeCentresPtr_);
143 deleteDemandDrivenData(faceAreaNormalsPtr_);
144 deleteDemandDrivenData(edgeAreaNormalsPtr_);
145 deleteDemandDrivenData(pointAreaNormalsPtr_);
146 deleteDemandDrivenData(faceCurvaturesPtr_);
147 deleteDemandDrivenData(edgeTransformTensorsPtr_);
151 void Foam::faMesh::clearGeom() const
155 Info<< "void faMesh::clearGeom() const : "
156 << "Clearing geometry" << endl;
160 deleteDemandDrivenData(S0Ptr_);
161 deleteDemandDrivenData(S00Ptr_);
162 deleteDemandDrivenData(correctPatchPointNormalsPtr_);
166 void Foam::faMesh::clearAddressing() const
170 Info<< "void faMesh::clearAddressing() const : "
171 << "Clearing addressing" << endl;
174 deleteDemandDrivenData(lduPtr_);
178 void Foam::faMesh::clearOut() const
182 deleteDemandDrivenData(globalMeshDataPtr_);
185 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
187 Foam::faMesh::faMesh(const polyMesh& pMesh)
189 GeoMesh<polyMesh>(pMesh),
190 edgeInterpolation(*this),
196 time().findInstance(meshDir(), "faceLabels"),
208 time().findInstance(meshDir(), "boundary"),
221 patchStartsPtr_(NULL),
225 edgeCentresPtr_(NULL),
226 faceAreaNormalsPtr_(NULL),
227 edgeAreaNormalsPtr_(NULL),
228 pointAreaNormalsPtr_(NULL),
229 faceCurvaturesPtr_(NULL),
230 edgeTransformTensorsPtr_(NULL),
231 correctPatchPointNormalsPtr_(NULL),
232 globalMeshDataPtr_(NULL),
234 curMotionTimeIndex_(pMesh.time().timeIndex())
238 Info<< "faMesh::faMesh(...) : "
239 << "Creating faMesh from IOobject" << endl;
242 setPrimitiveMeshData();
244 // Calculate topology for the patches (processor-processor comms etc.)
245 boundary_.updateMesh();
247 // Calculate the geometry for the patches (transformation tensors etc.)
248 boundary_.calcGeometry();
250 if (isFile(pMesh.time().timePath()/"S0"))
252 S0Ptr_ = new DimensionedField<scalar, areaMesh>
269 // Construct from components without boundary.
272 const polyMesh& pMesh,
273 const labelList& faceLabels
276 GeoMesh<polyMesh>(pMesh),
277 edgeInterpolation(*this),
283 mesh_.facesInstance(),
296 mesh_.facesInstance(),
310 patchStartsPtr_(NULL),
314 edgeCentresPtr_(NULL),
315 faceAreaNormalsPtr_(NULL),
316 edgeAreaNormalsPtr_(NULL),
317 pointAreaNormalsPtr_(NULL),
318 faceCurvaturesPtr_(NULL),
319 edgeTransformTensorsPtr_(NULL),
320 correctPatchPointNormalsPtr_(NULL),
321 globalMeshDataPtr_(NULL),
323 curMotionTimeIndex_(pMesh.time().timeIndex())
327 Info<< "faMesh::faMesh(...) : "
328 << "Creating faMesh from components" << endl;
333 // Construct from definition field
337 const fileName& defFile
340 GeoMesh<polyMesh>(m),
341 edgeInterpolation(*this),
347 mesh_.facesInstance(),
360 mesh_.facesInstance(),
374 patchStartsPtr_(NULL),
378 edgeCentresPtr_(NULL),
379 faceAreaNormalsPtr_(NULL),
380 edgeAreaNormalsPtr_(NULL),
381 pointAreaNormalsPtr_(NULL),
382 faceCurvaturesPtr_(NULL),
383 edgeTransformTensorsPtr_(NULL),
384 correctPatchPointNormalsPtr_(NULL),
385 globalMeshDataPtr_(NULL),
387 curMotionTimeIndex_(m.time().timeIndex())
391 Info<< "faMesh::faMesh(...) : "
392 << "Creating faMesh from definition file" << endl;
395 // Reading faMeshDefinition dictionary
396 IOdictionary faMeshDefinition
401 mesh_.time().constant(),
409 wordList polyMeshPatches
411 faMeshDefinition.lookup("polyMeshPatches")
414 dictionary bndDict = faMeshDefinition.subDict("boundary");
416 wordList faPatchNames = bndDict.toc();
418 List<faPatchData> faPatches(faPatchNames.size() + 1);
420 forAll (faPatchNames, patchI)
422 dictionary curPatchDict =
423 bndDict.subDict(faPatchNames[patchI]);
425 faPatches[patchI].name_ = faPatchNames[patchI];
427 faPatches[patchI].type_ =
428 word(curPatchDict.lookup("type"));
430 faPatches[patchI].ownPolyPatchID_ =
431 mesh_.boundaryMesh().findPatchID
433 word(curPatchDict.lookup("ownerPolyPatch"))
436 faPatches[patchI].ngbPolyPatchID_ =
437 mesh_.boundaryMesh().findPatchID
439 word(curPatchDict.lookup("neighbourPolyPatch"))
444 // Setting faceLabels list size
447 labelList patchIDs(polyMeshPatches.size(), -1);
449 forAll (polyMeshPatches, patchI)
452 mesh_.boundaryMesh().findPatchID(polyMeshPatches[patchI]);
454 size += mesh_.boundaryMesh()[patchIDs[patchI]].size();
457 faceLabels_ = labelList(size, -1);
460 // Filling of faceLabels list
465 forAll (polyMeshPatches, patchI)
467 label start = mesh_.boundaryMesh()[patchIDs[patchI]].start();
469 label size = mesh_.boundaryMesh()[patchIDs[patchI]].size();
471 for(label i = 0; i < size; i++)
473 faceLabels_[++faceI] = start + i;
478 // Determination of faPatch ID for each boundary edge.
479 // Result is in the bndEdgeFaPatchIDs list
480 labelList faceCells(faceLabels_.size(), -1);
482 forAll (faceCells, faceI)
484 label faceID = faceLabels_[faceI];
486 faceCells[faceI] = mesh_.faceOwner()[faceID];
489 labelList meshEdges =
497 const labelListList& edgeFaces = mesh_.edgeFaces();
499 const label nTotalEdges = patch().nEdges();
500 const label nInternalEdges = patch().nInternalEdges();
502 labelList bndEdgeFaPatchIDs(nTotalEdges - nInternalEdges, -1);
504 for (label edgeI = nInternalEdges; edgeI < nTotalEdges; edgeI++)
506 label curMeshEdge = meshEdges[edgeI];
508 labelList curEdgePatchIDs(2, -1);
512 forAll (edgeFaces[curMeshEdge], faceI)
514 label curFace = edgeFaces[curMeshEdge][faceI];
516 label curPatchID = mesh_.boundaryMesh().whichPatch(curFace);
518 if (curPatchID != -1)
520 curEdgePatchIDs[++patchI] = curPatchID;
524 for(label pI = 0; pI < faPatches.size() - 1; pI++)
529 curEdgePatchIDs[0] == faPatches[pI].ownPolyPatchID_
530 && curEdgePatchIDs[1] == faPatches[pI].ngbPolyPatchID_
534 curEdgePatchIDs[1] == faPatches[pI].ownPolyPatchID_
535 && curEdgePatchIDs[0] == faPatches[pI].ngbPolyPatchID_
539 bndEdgeFaPatchIDs[edgeI - nInternalEdges] = pI;
546 // Set edgeLabels for each faPatch
547 for(label pI=0; pI<(faPatches.size()-1); pI++)
549 SLList<label> tmpList;
551 forAll (bndEdgeFaPatchIDs, eI)
553 if (bndEdgeFaPatchIDs[eI] == pI)
555 tmpList.append(nInternalEdges + eI);
559 faPatches[pI].edgeLabels_ = tmpList;
562 // Check for undefined edges
563 SLList<label> tmpList;
565 forAll (bndEdgeFaPatchIDs, eI)
567 if (bndEdgeFaPatchIDs[eI] == -1)
569 tmpList.append(nInternalEdges + eI);
573 if (tmpList.size() > 0)
575 label pI = faPatches.size()-1;
577 faPatches[pI].name_ = "undefined";
578 faPatches[pI].type_ = "patch";
579 faPatches[pI].edgeLabels_ = tmpList;
582 // Add good patches to faMesh
583 SLList<faPatch*> faPatchLst;
585 for(label pI = 0; pI < faPatches.size(); pI++)
587 faPatches[pI].dict_.add("type", faPatches[pI].type_);
588 faPatches[pI].dict_.add("edgeLabels", faPatches[pI].edgeLabels_);
589 faPatches[pI].dict_.add
592 faPatches[pI].ngbPolyPatchID_
595 if(faPatches[pI].edgeLabels_.size() > 0)
610 addFaPatches(List<faPatch*>(faPatchLst));
612 setPrimitiveMeshData();
614 // Calculate topology for the patches (processor-processor comms etc.)
615 boundary_.updateMesh();
617 // Calculate the geometry for the patches (transformation tensors etc.)
618 boundary_.calcGeometry();
620 if (isFile(mesh_.time().timePath()/"S0"))
622 S0Ptr_ = new DimensionedField<scalar, areaMesh>
639 // Construct from polyPatch
643 const label polyPatchID
646 GeoMesh<polyMesh>(m),
647 edgeInterpolation(*this),
653 mesh_.facesInstance(),
659 labelList(m.boundaryMesh()[polyPatchID].size(), -1)
666 mesh_.facesInstance(),
680 patchStartsPtr_(NULL),
684 edgeCentresPtr_(NULL),
685 faceAreaNormalsPtr_(NULL),
686 edgeAreaNormalsPtr_(NULL),
687 pointAreaNormalsPtr_(NULL),
688 faceCurvaturesPtr_(NULL),
689 edgeTransformTensorsPtr_(NULL),
690 correctPatchPointNormalsPtr_(NULL),
691 globalMeshDataPtr_(NULL),
693 curMotionTimeIndex_(m.time().timeIndex())
697 Info<< "faMesh::faMesh(...) : "
698 << "Creating faMesh from polyPatch" << endl;
702 forAll(faceLabels_, faceI)
705 mesh_.boundaryMesh()[polyPatchID].start() + faceI;
709 const indirectPrimitivePatch& bp = patch();
711 const label nTotalEdges = bp.nEdges();
713 const label nInternalEdges = bp.nInternalEdges();
715 labelList edgeLabels(nTotalEdges-nInternalEdges, -1);
717 forAll(edgeLabels, edgeI)
719 edgeLabels[edgeI] = nInternalEdges + edgeI;
722 dictionary patchDict;
724 patchDict.add("type", "patch");
725 patchDict.add("edgeLabels", edgeLabels);
726 patchDict.add("ngbPolyPatchIndex", -1);
728 List<faPatch*> faPatchLst(1);
731 faPatch::New("default", patchDict, 0, boundary()).ptr();
733 addFaPatches(faPatchLst);
735 setPrimitiveMeshData();
737 // Calculate topology for the patches (processor-processor comms etc.)
738 boundary_.updateMesh();
740 // Calculate the geometry for the patches (transformation tensors etc.)
741 boundary_.calcGeometry();
745 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
747 Foam::faMesh::~faMesh()
752 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
754 Foam::fileName Foam::faMesh::meshDir() const
756 return mesh_.dbDir()/meshSubDir;
760 const Foam::Time& Foam::faMesh::time() const
766 const Foam::fileName& Foam::faMesh::pointsInstance() const
768 return mesh_.pointsInstance();
772 const Foam::fileName& Foam::faMesh::facesInstance() const
774 return mesh_.facesInstance();
778 const Foam::indirectPrimitivePatch& Foam::faMesh::patch() const
782 patchPtr_ = new indirectPrimitivePatch
797 Foam::indirectPrimitivePatch& Foam::faMesh::patch()
801 patchPtr_ = new indirectPrimitivePatch
816 const Foam::pointField& Foam::faMesh::points() const
818 return patch().localPoints();
822 const Foam::edgeList& Foam::faMesh::edges() const
828 const Foam::faceList& Foam::faMesh::faces() const
830 return patch().localFaces();
834 void Foam::faMesh::addFaPatches(const List<faPatch*>& p)
838 Info<< "void faMesh::addFaPatches(const List<faPatch*>& p) : "
839 << "Adding patches to faMesh" << endl;
842 if (boundary().size() > 0)
844 FatalErrorIn("void faMesh::addPatches(const List<faPatch*>& p)")
845 << "boundary already exists"
846 << abort(FatalError);
849 boundary_.setSize(p.size());
853 boundary_.set(patchI, p[patchI]);
856 setPrimitiveMeshData();
858 boundary_.checkDefinition();
860 // Calculate the geometry for the patches (transformation tensors etc.)
861 boundary_.calcGeometry();
865 const Foam::objectRegistry& Foam::faMesh::thisDb() const
867 return mesh_.thisDb();
871 const Foam::faBoundaryMesh& Foam::faMesh::boundary() const
877 const Foam::labelList& Foam::faMesh::patchStarts() const
879 if (!patchStartsPtr_)
884 return *patchStartsPtr_;
888 const Foam::edgeVectorField& Foam::faMesh::Le() const
899 const Foam::edgeScalarField& Foam::faMesh::magLe() const
910 const Foam::areaVectorField& Foam::faMesh::areaCentres() const
921 const Foam::edgeVectorField& Foam::faMesh::edgeCentres() const
923 if (!edgeCentresPtr_)
928 return *edgeCentresPtr_;
932 const Foam::DimensionedField<Foam::scalar, Foam::areaMesh>&
933 Foam::faMesh::S() const
944 const Foam::DimensionedField<Foam::scalar, Foam::areaMesh>&
945 Foam::faMesh::S0() const
949 FatalErrorIn("faMesh::S0() const")
950 << "S0 is not available"
951 << abort(FatalError);
958 const Foam::DimensionedField<Foam::scalar, Foam::areaMesh>&
959 Foam::faMesh::S00() const
963 S00Ptr_ = new DimensionedField<scalar, areaMesh>
976 S0Ptr_->writeOpt() = IOobject::AUTO_WRITE;
983 const Foam::areaVectorField& Foam::faMesh::faceAreaNormals() const
985 if (!faceAreaNormalsPtr_)
987 calcFaceAreaNormals();
990 return *faceAreaNormalsPtr_;
994 const Foam::edgeVectorField& Foam::faMesh::edgeAreaNormals() const
996 if (!edgeAreaNormalsPtr_)
998 calcEdgeAreaNormals();
1001 return *edgeAreaNormalsPtr_;
1005 const Foam::vectorField& Foam::faMesh::pointAreaNormals() const
1007 if (!pointAreaNormalsPtr_)
1009 calcPointAreaNormals();
1013 calcPointAreaNormalsByQuadricsFit();
1017 return *pointAreaNormalsPtr_;
1021 const Foam::areaScalarField& Foam::faMesh::faceCurvatures() const
1023 if (!faceCurvaturesPtr_)
1025 calcFaceCurvatures();
1028 return *faceCurvaturesPtr_;
1032 const Foam::FieldField<Foam::Field, Foam::tensor>&
1033 Foam::faMesh::edgeTransformTensors() const
1035 if (!edgeTransformTensorsPtr_)
1037 calcEdgeTransformTensors();
1040 return *edgeTransformTensorsPtr_;
1044 // Return global mesh data
1045 const Foam::faGlobalMeshData& Foam::faMesh::globalData() const
1047 if (!globalMeshDataPtr_)
1049 globalMeshDataPtr_ = new faGlobalMeshData(*this);
1052 return *globalMeshDataPtr_;
1056 const Foam::lduAddressing& Foam::faMesh::lduAddr() const
1060 calcLduAddressing();
1067 Foam::tmp<Foam::scalarField>
1068 Foam::faMesh::movePoints(const vectorField& newPoints)
1072 // Grab old time areas if the time has been incremented
1073 if (curMotionTimeIndex_ < operator()().time().timeIndex())
1075 if (S00Ptr_ && S0Ptr_)
1086 S0Ptr_ = new DimensionedField<scalar, areaMesh>
1101 curMotionTimeIndex_ = operator()().time().timeIndex();
1104 clearGeomNotAreas();
1106 patch().movePoints(newPoints);
1107 boundary_.movePoints(newPoints);
1108 edgeInterpolation::movePoints();
1110 tmp<scalarField> tresult(new scalarField(nEdges(), 0.0));
1116 //- Return true if point normals should be corrected for a patch
1117 bool Foam::faMesh::correctPatchPointNormals(const label patchID) const
1119 if((patchID < 0) || (patchID >= boundary().size()))
1123 "bool correctPatchPointNormals(const label patchID) const"
1124 ) << "patchID is not in the valid range"
1125 << abort(FatalError);
1128 if(correctPatchPointNormalsPtr_)
1130 return (*correctPatchPointNormalsPtr_)[patchID];
1137 //- Set patch point normals corrections
1138 Foam::boolList& Foam::faMesh::correctPatchPointNormals() const
1140 if(!correctPatchPointNormalsPtr_)
1142 correctPatchPointNormalsPtr_ =
1143 new boolList(boundary().size(), false);
1146 return *correctPatchPointNormalsPtr_;
1150 bool Foam::faMesh::write() const
1152 faceLabels_.write();
1159 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1161 bool Foam::faMesh::operator!=(const faMesh& m) const
1167 bool Foam::faMesh::operator==(const faMesh& m) const
1173 // ************************************************************************* //