From 6c22a20c7220891c458fac8629f386ea2779c64a Mon Sep 17 00:00:00 2001 From: Sandeep Menon Date: Tue, 23 Sep 2014 13:56:37 -0500 Subject: [PATCH] BUGFIX: Bring sources up to date with repository --- .../mesquiteMotionSolver.C | 1065 ++++++++++++++--- .../mesquiteMotionSolver.H | 35 +- 2 files changed, 953 insertions(+), 147 deletions(-) diff --git a/src/dynamicMesh/meshMotion/mesquiteMotionSolver/mesquiteMotionSolver.C b/src/dynamicMesh/meshMotion/mesquiteMotionSolver/mesquiteMotionSolver.C index 6196a4adc..828b94ec3 100644 --- a/src/dynamicMesh/meshMotion/mesquiteMotionSolver/mesquiteMotionSolver.C +++ b/src/dynamicMesh/meshMotion/mesquiteMotionSolver/mesquiteMotionSolver.C @@ -33,6 +33,7 @@ License #include "addToRunTimeSelectionTable.H" #include "polyMesh.H" +#include "tetPointRef.H" #include "matchPoints.H" #include "DimensionedField.H" #include "pointPatchField.H" @@ -68,7 +69,9 @@ mesquiteMotionSolver::mesquiteMotionSolver twoDMesh_(mesh.nGeometricD() == 2 ? true : false), arraysInitialized_(false), nPoints_(mesh.nPoints()), - nCells_(mesh.nCells()), + nCells_(0), + decompType_(-1), + nDecompPoints_(0), surfaceSmoothing_(false), volumeCorrection_(false), volCorrTolerance_(1e-20), @@ -108,7 +111,9 @@ mesquiteMotionSolver::mesquiteMotionSolver twoDMesh_(mesh.nGeometricD() == 2 ? true : false), arraysInitialized_(false), nPoints_(mesh.nPoints()), - nCells_(mesh.nCells()), + nCells_(0), + decompType_(-1), + nDecompPoints_(0), surfaceSmoothing_(false), volumeCorrection_(false), volCorrTolerance_(1e-20), @@ -1131,6 +1136,34 @@ void mesquiteMotionSolver::readOptions() tcOuter_.add_iteration_limit(1); } + + // Set decomposition type, if available + if (optionsDict.found("decompType")) + { + word dType(optionsDict.lookup("decompType")); + + if (dType == "cell") + { + decompType_ = 1; + } + else + if (dType == "face") + { + decompType_ = 2; + } + else + { + FatalErrorIn("void mesquiteMotionSolver::readOptions()") + << "Unknown decomposition type: " << dType + << "Available types are: cell or face" + << abort(FatalError); + } + } + else + { + // Set default + decompType_ = 2; + } } @@ -1146,6 +1179,7 @@ void mesquiteMotionSolver::initArrays() gradEdge_.setSize(pIDs_.size()); localPts_.setSize(pIDs_.size()); edgeMarker_.setSize(pIDs_.size()); + edgeConstant_.setSize(pIDs_.size()); label totalSize = 0; @@ -1158,6 +1192,7 @@ void mesquiteMotionSolver::initArrays() localPts_[patchI].setSize(nPts, vector::zero); gradEdge_[patchI].setSize(nEdg, vector::zero); edgeMarker_[patchI].setSize(nEdg, 1.0); + edgeConstant_[patchI].setSize(nEdg, 1.0); // Accumulate the total size totalSize += nPts; @@ -1178,6 +1213,7 @@ void mesquiteMotionSolver::initArrays() // Prepare the boundary condition vectorField forAll(pIDs_, patchI) { + const label pOffset = offsets_[patchI]; const edgeList& edges = boundary[pIDs_[patchI]].edges(); for @@ -1187,8 +1223,8 @@ void mesquiteMotionSolver::initArrays() i++ ) { - bdy_[edges[i][0] + offsets_[patchI]] = vector::zero; - bdy_[edges[i][1] + offsets_[patchI]] = vector::zero; + bdy_[edges[i][0] + pOffset] = vector::zero; + bdy_[edges[i][1] + pOffset] = vector::zero; } } @@ -1206,37 +1242,75 @@ void mesquiteMotionSolver::initArrays() return; } + const dictionary& optionsDict = subDict("mesquiteOptions"); + + label nPolyhedra = 0; + label nCellPoints = 0, nFacePoints = 0; + // Construct shape recognizers - label nUnknown = 0; FixedList nTypes(0); FixedList, 4> matcher; FixedList cellType; // Set types - matcher[0].set(new hexMatcher()); - cellType[0] = Mesquite::HEXAHEDRON; + bool standardTypes = false; - matcher[1].set(new tetMatcher()); - cellType[1] = Mesquite::TETRAHEDRON; + if (optionsDict.found("standardCellTypes")) + { + standardTypes = readBool(optionsDict.lookup("standardCellTypes")); + } - matcher[2].set(new pyrMatcher()); - cellType[2] = Mesquite::PYRAMID; + if (standardTypes) + { + matcher[0].set(new tetMatcher()); + cellType[0] = Mesquite::TETRAHEDRON; - matcher[3].set(new prismMatcher()); - cellType[3] = Mesquite::PRISM; + matcher[1].set(new hexMatcher()); + cellType[1] = Mesquite::HEXAHEDRON; + + matcher[2].set(new pyrMatcher()); + cellType[2] = Mesquite::PYRAMID; + + matcher[3].set(new prismMatcher()); + cellType[3] = Mesquite::PRISM; + } + else + { + // No standard types. + // Default to tetrahedra, and decompose the rest. + matcher[0].set(new tetMatcher()); + cellType[0] = Mesquite::TETRAHEDRON; + + matcher[1].set(NULL); + matcher[2].set(NULL); + matcher[3].set(NULL); + } const faceList& meshFaces = mesh().faces(); const cellList& meshCells = mesh().cells(); const labelList& faceOwner = mesh().faceOwner(); + // Face marker list + List faceMarker; + + if (decompType_ == 2) + { + faceMarker.setSize(meshFaces.size(), labelPair(-1, -1)); + } + forAll(meshCells, cellI) { bool foundMatch = false; forAll(matcher, indexI) { - if (matcher[indexI]->isA(mesh(), cellI)) + if + ( + matcher[indexI].valid() && + matcher[indexI]->isA(mesh(), cellI) + ) { + nCells_++; nTypes[indexI]++; foundMatch = true; @@ -1244,43 +1318,126 @@ void mesquiteMotionSolver::initArrays() } } - if (!foundMatch) + if (foundMatch) { - nUnknown++; + continue; + } + + // Assume polyhedron + nPolyhedra++; + + // Decompose into tets. + const cell& checkCell = meshCells[cellI]; + + // Add a central point for the cell + nCellPoints++; + nDecompPoints_++; + + forAll(checkCell, faceI) + { + const face& checkFace = meshFaces[checkCell[faceI]]; + + switch (decompType_) + { + case 1: + { + nCells_ += (checkFace.size() - 2); + nTypes[0] += (checkFace.size() - 2); + + break; + } + + case 2: + { + if (checkFace.size() == 3) + { + nCells_++; + nTypes[0]++; + } + else + { + // Add a central point for the face + labelPair& fPair = faceMarker[checkCell[faceI]]; + + if (fPair.first() == -1) + { + fPair.first() = 1; + + nFacePoints++; + nDecompPoints_++; + } + + nCells_ += checkFace.size(); + nTypes[0] += checkFace.size(); + } + + break; + } + + default: + { + FatalErrorIn("void mesquiteMotionSolver::initArrays()") + << "Unknown polyhedron decomposition type." + << abort(FatalError); + + break; + } + } } } if (debug) { - Pout<< "nHex = " << nTypes[0] << nl - << "nTet = " << nTypes[1] << nl - << "nPyr = " << nTypes[2] << nl - << "nPrism = " << nTypes[3] << nl - << "nUnknown = " << nUnknown << endl; + Pout<< "nTet = " << nTypes[0] << nl + << "nHex = " << nTypes[1] << nl + << "nPyr = " << nTypes[2] << nl + << "nPrism = " << nTypes[3] << nl + << "nPolyhedra = " << nPolyhedra << endl; } label nCellToNode = ( - (8 * nTypes[0]) - + (4 * nTypes[1]) + (4 * nTypes[0]) + + (8 * nTypes[1]) + (5 * nTypes[2]) + (6 * nTypes[3]) ); // Prepare arrays for mesquite - vtxCoords_.setSize(3 * nPoints_); + vtxCoords_.setSize(3 * (nPoints_ + nDecompPoints_)); cellToNode_.setSize(nCellToNode); - fixFlags_.setSize(nPoints_); + fixFlags_.setSize(nPoints_ + nDecompPoints_); mixedTypes_.setSize(nCells_); + decompCellCentres_.setSize(nCellPoints); + decompFaceCentres_.setSize(nFacePoints); + + // Reset faceMarker + if (nFacePoints) + { + forAll(faceMarker, faceI) + { + faceMarker[faceI].first() = -1; + } + } + + // Reset counters + nDecompPoints_ = 0; + nCellPoints = 0, nFacePoints = 0; // Set connectivity information label cIndex = 0, cellIndex = 0; forAll(meshCells, cellI) { + bool foundMatch = false; + forAll(matcher, indexI) { - if (matcher[indexI]->isA(mesh(), cellI)) + if + ( + matcher[indexI].valid() && + matcher[indexI]->isA(mesh(), cellI) + ) { // Match shape matcher[indexI]->matchShape @@ -1303,13 +1460,160 @@ void mesquiteMotionSolver::initArrays() // Set element type mixedTypes_[cellIndex++] = cellType[indexI]; + foundMatch = true; + break; + } + } + + if (foundMatch) + { + continue; + } + + // Decompose into tets. + const cell& checkCell = meshCells[cellI]; + + // Add a central point for the cell + label cellPoint = nPoints_ + nDecompPoints_; + + decompCellCentres_[nCellPoints].first() = cellI; + decompCellCentres_[nCellPoints].second() = cellPoint; + + nCellPoints++; + nDecompPoints_++; + + switch (decompType_) + { + case 1: + { + forAll(checkCell, faceI) + { + const face& checkFace = meshFaces[checkCell[faceI]]; + const label& checkOwner = faceOwner[checkCell[faceI]]; + + if (checkOwner == cellI) + { + for (label nI = (checkFace.size() - 1); nI > 1; nI--) + { + cellToNode_[cIndex++] = checkFace[0]; + cellToNode_[cIndex++] = checkFace[nI]; + cellToNode_[cIndex++] = checkFace[nI - 1]; + cellToNode_[cIndex++] = cellPoint; + + mixedTypes_[cellIndex++] = cellType[0]; + } + } + else + { + for (label nI = 1; nI < (checkFace.size() - 1); nI++) + { + cellToNode_[cIndex++] = checkFace[0]; + cellToNode_[cIndex++] = checkFace[nI]; + cellToNode_[cIndex++] = checkFace[nI + 1]; + cellToNode_[cIndex++] = cellPoint; + + mixedTypes_[cellIndex++] = cellType[0]; + } + } + } + + break; + } + + case 2: + { + forAll(checkCell, faceI) + { + const face& checkFace = meshFaces[checkCell[faceI]]; + const label& checkOwner = faceOwner[checkCell[faceI]]; + + if (checkFace.size() == 3) + { + if (checkOwner == cellI) + { + cellToNode_[cIndex++] = checkFace[2]; + cellToNode_[cIndex++] = checkFace[1]; + cellToNode_[cIndex++] = checkFace[0]; + cellToNode_[cIndex++] = cellPoint; + + mixedTypes_[cellIndex++] = cellType[0]; + } + else + { + cellToNode_[cIndex++] = checkFace[0]; + cellToNode_[cIndex++] = checkFace[1]; + cellToNode_[cIndex++] = checkFace[2]; + cellToNode_[cIndex++] = cellPoint; + + mixedTypes_[cellIndex++] = cellType[0]; + } + } + else + { + // Add a central point for the face + labelPair& fPair = faceMarker[checkCell[faceI]]; + + if (fPair.first() == -1) + { + fPair.first() = checkCell[faceI]; + fPair.second() = nPoints_ + nDecompPoints_; + + nFacePoints++; + nDecompPoints_++; + } + + if (checkOwner == cellI) + { + forAllReverse(checkFace, nI) + { + cellToNode_[cIndex++] = checkFace[nI]; + cellToNode_[cIndex++] = checkFace.prevLabel(nI); + cellToNode_[cIndex++] = fPair.second(); + cellToNode_[cIndex++] = cellPoint; + + mixedTypes_[cellIndex++] = cellType[0]; + } + } + else + { + forAll(checkFace, nI) + { + cellToNode_[cIndex++] = checkFace[nI]; + cellToNode_[cIndex++] = checkFace.nextLabel(nI); + cellToNode_[cIndex++] = fPair.second(); + cellToNode_[cIndex++] = cellPoint; + + mixedTypes_[cellIndex++] = cellType[0]; + } + } + } + } + break; } } } + // Condense the faceMarker + if (nFacePoints) + { + nFacePoints = 0; + + forAll(faceMarker, faceI) + { + const labelPair& fPair = faceMarker[faceI]; + + if (fPair.first() > -1) + { + decompFaceCentres_[nFacePoints++] = fPair; + } + } + } + + faceMarker.clear(); + // Fix patch information, but blank out first - forAll(refPoints_, pointI) + forAll(fixFlags_, pointI) { fixFlags_[pointI] = 0; } @@ -1330,9 +1634,30 @@ void mesquiteMotionSolver::initArrays() } } - // Optionally fix additional zone points - const dictionary& optionsDict = subDict("mesquiteOptions"); + // Fix points on decomposed boundary faces + forAll(decompFaceCentres_, indexI) + { + label fIndex = decompFaceCentres_[indexI].first(); + label pIndex = decompFaceCentres_[indexI].second(); + label patchI = boundary.whichPatch(fIndex); + + if (patchI < 0) + { + continue; + } + + // Leave processor boundaries out. + if (boundary[patchI].type() == "processor") + { + continue; + } + + // Point is on physical boundary patch + fixFlags_[pIndex] = 1; + } + + // Optionally fix additional zone points if (optionsDict.found("fixPointsZone")) { wordList fixZones = optionsDict.subDict("fixPointsZone").toc(); @@ -1624,6 +1949,7 @@ void mesquiteMotionSolver::initParallelSurfaceSmoothing() forAll(pIDs_, patchI) { + const label pOffset = offsets_[patchI]; const pointField& points = boundary[pIDs_[patchI]].localPoints(); forAll(boundary, patchJ) @@ -1648,8 +1974,8 @@ void mesquiteMotionSolver::initParallelSurfaceSmoothing() } // Fetch references - Map