bool Foam::ggiPolyPatch::order ( const primitivePatch& pp, labelList& faceMap, labelList& rotation ) const { faceMap.setSize(pp.size(), -1); rotation.setSize(pp.size(), 0); // Nothing changes return false; }
bool Foam::primitiveMesh::calcPointOrder ( label& nInternalPoints, labelList& oldToNew, const faceList& faces, const label nInternalFaces, const label nPoints ) { // Internal points are points that are not used by a boundary face. // Map from old to new position oldToNew.setSize(nPoints); oldToNew = -1; // 1. Create compact addressing for boundary points. Start off by indexing // from 0 inside oldToNew. (shifted up later on) label nBoundaryPoints = 0; for (label faceI = nInternalFaces; faceI < faces.size(); faceI++) { const face& f = faces[faceI]; forAll(f, fp) { label pointI = f[fp]; if (oldToNew[pointI] == -1) { oldToNew[pointI] = nBoundaryPoints++; } } }
bool Foam::regionCouplePolyPatch::order ( const primitivePatch& pp, labelList& faceMap, labelList& rotation ) const { faceMap.setSize(pp.size()); faceMap = -1; rotation.setSize(pp.size()); rotation = 0; // Nothing changes return false; }
Foam::label Foam::edgeMesh::regions(labelList& edgeRegion) const { edgeRegion.setSize(edges_.size()); edgeRegion = -1; label startEdgeI = 0; label currentRegion = 0; while (true) { while (startEdgeI < edges_.size() && edgeRegion[startEdgeI] != -1) { startEdgeI++; } if (startEdgeI == edges_.size()) { break; } // Found edge that has not yet been assigned a region. // Mark connected region with currentRegion starting at startEdgeI. edgeRegion[startEdgeI] = currentRegion; labelList edgesToVisit(1, startEdgeI); while (edgesToVisit.size()) { // neighbours of current edgesToVisit DynamicList<label> newEdgesToVisit(edgesToVisit.size()); // Mark all point connected edges with current region. forAll(edgesToVisit, i) { label edgeI = edgesToVisit[i]; // Mark connected edges const edge& e = edges_[edgeI]; forAll(e, fp) { const labelList& pEdges = pointEdges()[e[fp]]; forAll(pEdges, pEdgeI) { label nbrEdgeI = pEdges[pEdgeI]; if (edgeRegion[nbrEdgeI] == -1) { edgeRegion[nbrEdgeI] = currentRegion; newEdgesToVisit.append(nbrEdgeI); } } } } edgesToVisit.transfer(newEdgesToVisit); }
void postProcessingWaves::readIndices ( const dictionary& indexDict, labelList& indices ) { // Getting the labelList of data set indices if (actionProperties_.lookupOrDefault<Switch>("allDataSets", false)) { labelList tempList( indexDict.lookup("index") ); indices.setSize( tempList.size() ); indices = tempList; } else { labelList tempList( actionProperties_.lookup("indices") ); indices.setSize( tempList.size() ); indices = tempList; } }
// Add added cells to labelList void Foam::multiDirRefinement::addCells ( const Map<label>& splitMap, labelList& labels ) { label newCellI = labels.size(); labels.setSize(labels.size() + splitMap.size()); forAllConstIter(Map<label>, splitMap, iter) { labels[newCellI++] = iter(); } }
Foam::label Foam::mergePoints ( const UList<Type>& points, const scalar mergeTol, const bool verbose, labelList& pointMap, const Type& origin ) { Type compareOrigin = origin; if (origin == Type::max) { if (points.size()) { compareOrigin = sum(points)/points.size(); } } // Create a old to new point mapping array pointMap.setSize(points.size()); pointMap = -1; if (points.empty()) { return points.size(); } // We're comparing distance squared to origin first. // Say if starting from two close points: // x, y, z // x+mergeTol, y+mergeTol, z+mergeTol // Then the magSqr of both will be // x^2+y^2+z^2 // x^2+y^2+z^2 + 2*mergeTol*(x+z+y) + mergeTol^2*... // so the difference will be 2*mergeTol*(x+y+z) const scalar mergeTolSqr = Foam::sqr(scalar(mergeTol)); // Sort points by magSqr const Field<Type> d(points - compareOrigin); List<scalar> magSqrD(d.size()); forAll(d, pointI) { magSqrD[pointI] = magSqr(d[pointI]); }
// Add added cells to labelList void Foam::multiDirRefinement::addCells ( const Map<label>& splitMap, labelList& labels ) { label newCellI = labels.size(); labels.setSize(labels.size() + splitMap.size()); for ( Map<label>::const_iterator iter = splitMap.begin(); iter != splitMap.end(); ++iter ) { labels[newCellI++] = iter(); } }
void Foam::hexCellLooper::makeFace ( const labelList& loop, const scalarField& loopWeights, labelList& faceVerts, pointField& facePoints ) const { facePoints.setSize(loop.size()); faceVerts.setSize(loop.size()); forAll(loop, cutI) { label cut = loop[cutI]; if (isEdge(cut)) { label edgeI = getEdge(cut); const edge& e = mesh().edges()[edgeI]; const point& v0 = mesh().points()[e.start()]; const point& v1 = mesh().points()[e.end()]; facePoints[cutI] = loopWeights[cutI]*v1 + (1.0-loopWeights[cutI])*v0; } else { label vertI = getVertex(cut); facePoints[cutI] = mesh().points()[vertI]; } faceVerts[cutI] = cutI; }
void Foam::domainDecomposition::append(labelList& lst, const label elem) { label sz = lst.size(); lst.setSize(sz+1); lst[sz] = elem; }
void Foam::CV2D::extractPatches ( wordList& patchNames, labelList& patchSizes, EdgeMap<label>& mapEdgesRegion, EdgeMap<label>& indirectPatchEdge ) const { label nPatches = qSurf_.patchNames().size() + 1; label defaultPatchIndex = qSurf_.patchNames().size(); patchNames.setSize(nPatches); patchSizes.setSize(nPatches, 0); mapEdgesRegion.clear(); const wordList& existingPatches = qSurf_.patchNames(); forAll(existingPatches, sP) { patchNames[sP] = existingPatches[sP]; } patchNames[defaultPatchIndex] = "CV2D_default_patch"; for ( Triangulation::Finite_edges_iterator eit = finite_edges_begin(); eit != finite_edges_end(); ++eit ) { Face_handle fOwner = eit->first; Face_handle fNeighbor = fOwner->neighbor(eit->second); Vertex_handle vA = fOwner->vertex(cw(eit->second)); Vertex_handle vB = fOwner->vertex(ccw(eit->second)); if ( (vA->internalOrBoundaryPoint() && !vB->internalOrBoundaryPoint()) || (vB->internalOrBoundaryPoint() && !vA->internalOrBoundaryPoint()) ) { point ptA = toPoint3D(vA->point()); point ptB = toPoint3D(vB->point()); label patchIndex = qSurf_.findPatch(ptA, ptB); if (patchIndex == -1) { patchIndex = defaultPatchIndex; WarningInFunction << "Dual face found that is not on a surface " << "patch. Adding to CV2D_default_patch." << endl; } edge e(fOwner->faceIndex(), fNeighbor->faceIndex()); patchSizes[patchIndex]++; mapEdgesRegion.insert(e, patchIndex); if (!pointPair(*vA, *vB)) { indirectPatchEdge.insert(e, 1); } } } }
void Foam::searchableSurfaceCollection::findNearest ( const pointField& samples, scalarField& minDistSqr, List<pointIndexHit>& nearestInfo, labelList& nearestSurf ) const { // Initialise nearestInfo.setSize(samples.size()); nearestInfo = pointIndexHit(); nearestSurf.setSize(samples.size()); nearestSurf = -1; List<pointIndexHit> hitInfo(samples.size()); const scalarField localMinDistSqr(samples.size(), GREAT); forAll(subGeom_, surfI) { subGeom_[surfI].findNearest ( cmptDivide // Transform then divide ( transform_[surfI].localPosition(samples), scale_[surfI] ), localMinDistSqr, hitInfo ); forAll(hitInfo, pointI) { if (hitInfo[pointI].hit()) { // Rework back into global coordinate sys. Multiply then // transform point globalPt = transform_[surfI].globalPosition ( cmptMultiply ( hitInfo[pointI].rawPoint(), scale_[surfI] ) ); scalar distSqr = magSqr(globalPt - samples[pointI]); if (distSqr < minDistSqr[pointI]) { minDistSqr[pointI] = distSqr; nearestInfo[pointI].setPoint(globalPt); nearestInfo[pointI].setHit(); nearestInfo[pointI].setIndex ( hitInfo[pointI].index() + indexOffset_[surfI] ); nearestSurf[pointI] = surfI; } } } }
bool Foam::matchPoints ( const UList<point>& pts0, const UList<point>& pts1, const UList<scalar>& matchDistances, const bool verbose, labelList& from0To1, const point& origin ) { from0To1.setSize(pts0.size()); from0To1 = -1; bool fullMatch = true; point compareOrigin = origin; if (origin == point(VGREAT, VGREAT, VGREAT)) { if (pts1.size()) { compareOrigin = sum(pts1)/pts1.size(); } } SortableList<scalar> pts0MagSqr(magSqr(pts0 - compareOrigin)); SortableList<scalar> pts1MagSqr(magSqr(pts1 - compareOrigin)); forAll(pts0MagSqr, i) { scalar dist0 = pts0MagSqr[i]; label face0I = pts0MagSqr.indices()[i]; scalar matchDist = matchDistances[face0I]; label startI = findLower(pts1MagSqr, 0.99999*dist0 - 2*matchDist); if (startI == -1) { startI = 0; } // Go through range of equal mag and find nearest vector. scalar minDistSqr = VGREAT; label minFacei = -1; for ( label j = startI; ( (j < pts1MagSqr.size()) && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist) ); j++ ) { label facei = pts1MagSqr.indices()[j]; // Compare actual vectors scalar distSqr = magSqr(pts0[face0I] - pts1[facei]); if (distSqr <= sqr(matchDist) && distSqr < minDistSqr) { minDistSqr = distSqr; minFacei = facei; } } if (minFacei == -1) { fullMatch = false; if (verbose) { Pout<< "Cannot find point in pts1 matching point " << face0I << " coord:" << pts0[face0I] << " in pts0 when using tolerance " << matchDist << endl; // Go through range of equal mag and find equal vector. Pout<< "Searching started from:" << startI << " in pts1" << endl; for ( label j = startI; ( (j < pts1MagSqr.size()) && (pts1MagSqr[j] < 1.00001*dist0 + 2*matchDist) ); j++ ) { label facei = pts1MagSqr.indices()[j]; Pout<< " Compared coord: " << pts1[facei] << " at index " << j << " with difference to point " << mag(pts1[facei] - pts0[face0I]) << endl; } } } from0To1[face0I] = minFacei; }
// Given a subset of cells determine the new global indices. The problem // is in the cells from neighbouring processors which need to be renumbered. void Foam::multiLevelDecomp::subsetGlobalCellCells ( const label nDomains, const label domainI, const labelList& dist, const labelListList& cellCells, const labelList& set, labelListList& subCellCells, labelList& cutConnections ) const { // Determine new index for cells by inverting subset labelList oldToNew(invert(cellCells.size(), set)); globalIndex globalCells(cellCells.size()); // Subset locally the elements for which I have data subCellCells = UIndirectList<labelList>(cellCells, set); // Get new indices for neighbouring processors List<Map<label>> compactMap; mapDistribute map(globalCells, subCellCells, compactMap); map.distribute(oldToNew); labelList allDist(dist); map.distribute(allDist); // Now we have: // oldToNew : the locally-compact numbering of all our cellCells. -1 if // cellCell is not in set. // allDist : destination domain for all our cellCells // subCellCells : indexes into oldToNew and allDist // Globally compact numbering for cells in set. globalIndex globalSubCells(set.size()); // Now subCellCells contains indices into oldToNew which are the // new locations of the neighbouring cells. cutConnections.setSize(nDomains); cutConnections = 0; forAll(subCellCells, subCelli) { labelList& cCells = subCellCells[subCelli]; // Keep the connections to valid mapped cells label newI = 0; forAll(cCells, i) { // Get locally-compact cell index of neighbouring cell label nbrCelli = oldToNew[cCells[i]]; if (nbrCelli == -1) { cutConnections[allDist[cCells[i]]]++; } else { // Reconvert local cell index into global one // Get original neighbour label celli = set[subCelli]; label oldNbrCelli = cellCells[celli][i]; // Get processor from original neighbour label proci = globalCells.whichProcID(oldNbrCelli); // Convert into global compact numbering cCells[newI++] = globalSubCells.toGlobal(proci, nbrCelli); } }
bool splineInterpolationWeights::valueWeights ( const scalar t, labelList& indices, scalarField& weights ) const { bool indexChanged = false; // linear interpolation if (samples_.size() <= 2) { return linearInterpolationWeights(samples_).valueWeights ( t, indices, weights ); } // Check if current timeIndex is still valid if ( index_ >= 0 && index_ < samples_.size() && ( samples_[index_] <= t && (index_ == samples_.size()-1 || t <= samples_[index_+1]) ) ) { // index_ still at correct slot } else { // search for correct index index_ = findLower(samples_, t); indexChanged = true; } // Clamp if outside table if (index_ == -1) { indices.setSize(1); weights.setSize(1); indices[0] = 0; weights[0] = 1; return indexChanged; } else if (index_ == samples_.size()-1) { indices.setSize(1); weights.setSize(1); indices[0] = samples_.size()-1; weights[0] = 1; return indexChanged; } label lo = index_; label hi = index_+1; // weighting scalar mu = (t - samples_[lo])/(samples_[hi] - samples_[lo]); scalar w0 = 0.5*(mu*(-1+mu*(2-mu))); // coeff of lo-1 scalar w1 = 0.5*(2+mu*(mu*(-5 + mu*(3)))); // coeff of lo scalar w2 = 0.5*(mu*(1 + mu*(4 + mu*(-3)))); // coeff of hi scalar w3 = 0.5*(mu*mu*(-1 + mu)); // coeff of hi+1 if (lo > 0) { if (hi < samples_.size()-1) { // Four points available indices.setSize(4); weights.setSize(4); indices[0] = lo-1; indices[1] = lo; indices[2] = hi; indices[3] = hi+1; weights[0] = w0; weights[1] = w1; weights[2] = w2; weights[3] = w3; } else { // No y3 available. Extrapolate: y3=3*y2-y1 indices.setSize(3); weights.setSize(3); indices[0] = lo-1; indices[1] = lo; indices[2] = hi; weights[0] = w0; weights[1] = w1 - w3; weights[2] = w2 + 2*w3; } } else { // No y0 available. Extrapolate: y0=2*y1-y2; if (hi < samples_.size()-1) { indices.setSize(3); weights.setSize(3); indices[0] = lo; indices[1] = hi; indices[2] = hi+1; weights[0] = w1 + 2*w0; weights[1] = w2 - w0; weights[2] = w3; } else { indices.setSize(2); weights.setSize(2); indices[0] = lo; indices[1] = hi; weights[0] = w1 + 2*w0 - w3; weights[1] = w2 - w0 + 2*w3; } } return indexChanged; }
bool linearInterpolationWeights::valueWeights ( const scalar t, labelList& indices, scalarField& weights ) const { bool indexChanged = false; // Check if current timeIndex is still valid if ( index_ >= 0 && index_ < samples_.size() && ( samples_[index_] <= t && (index_ == samples_.size()-1 || t <= samples_[index_+1]) ) ) { // index_ still at correct slot } else { // search for correct index index_ = findLower(samples_, t); indexChanged = true; } if (index_ == -1) { // Use first element only indices.setSize(1); weights.setSize(1); indices[0] = 0; weights[0] = 1.0; } else if (index_ == samples_.size()-1) { // Use last element only indices.setSize(1); weights.setSize(1); indices[0] = samples_.size()-1; weights[0] = 1.0; } else { // Interpolate indices.setSize(2); weights.setSize(2); indices[0] = index_; indices[1] = index_+1; scalar t0 = samples_[indices[0]]; scalar t1 = samples_[indices[1]]; scalar deltaT = t1-t0; weights[0] = (t1-t)/deltaT; weights[1] = 1.0-weights[0]; } return indexChanged; }
bool linearInterpolationWeights::integrationWeights ( const scalar t1, const scalar t2, labelList& indices, scalarField& weights ) const { if (t2 < t1-VSMALL) { FatalErrorIn("linearInterpolationWeights::integrationWeights(..)") << "Integration should be in positive direction." << " t1:" << t1 << " t2:" << t2 << exit(FatalError); } // Currently no fancy logic on cached index like in value //- Find lower or equal index label i1 = findLower(samples_, t1, 0, lessEqOp<scalar>()); //- Find lower index label i2 = findLower(samples_, t2); // For now just fail if any outside table if (i1 == -1 || i2 == samples_.size()-1) { FatalErrorIn("linearInterpolationWeights::integrationWeights(..)") << "Integrating outside table " << samples_[0] << ".." << samples_.last() << " not implemented." << " t1:" << t1 << " t2:" << t2 << exit(FatalError); } label nIndices = i2-i1+2; // Determine if indices already correct bool anyChanged = false; if (nIndices != indices.size()) { anyChanged = true; } else { // Closer check label index = i1; forAll(indices, i) { if (indices[i] != index) { anyChanged = true; break; } index++; } } indices.setSize(nIndices); weights.setSize(nIndices); weights = 0.0; // Sum from i1+1 to i2+1 for (label i = i1+1; i <= i2; i++) { scalar d = samples_[i+1]-samples_[i]; indices[i-i1] = i; weights[i-i1] += 0.5*d; indices[i+1-i1] = i+1; weights[i+1-i1] += 0.5*d; } // Add from i1 to t1 { Pair<scalar> i1Tot1 = integrationWeights(i1, t1); indices[0] = i1; weights[0] += i1Tot1.first(); indices[1] = i1+1; weights[1] += i1Tot1.second(); } // Subtract from t2 to i2+1 { Pair<scalar> wghts = integrationWeights(i2, t2); indices[i2-i1] = i2; weights[i2-i1] += -wghts.first(); indices[i2-i1+1] = i2+1; weights[i2-i1+1] += -wghts.second(); } return anyChanged; }
void Foam::equationReader::removePowExponents ( const label index, tokenList& tl, PtrList<equationOperation>& map, labelList& opLvl, labelList& pl ) const { // Remove pow(a,b) exponent part 'b' from an equation and create a sub- // equation. label tokenI(0); while (tokenI < map.size()) { if (map[tokenI].operation() == equationOperation::otpow) { // Found a 'pow('. Look for ','; fail on ')', or end of list // pl checks ensure the ',' or ')' relate to the 'pow(', and not // another function / parethesis const label powFoundAt(tokenI); const label pLvl(pl[tokenI]); while ((opLvl[tokenI] != 5) || (pl[tokenI] != pLvl)) { if ( ((opLvl[tokenI] == -4) && (pl[tokenI] == pLvl)) || (tokenI == (map.size() - 1)) ) { OStringStream description; description << "pow() function takes two arguments."; fatalParseError ( index, tl, powFoundAt, tokenI, "equationReader::removePowExponents", description ); } tokenI++; } // Found 'pow( ... ,' look for ')', fail on list end const label commaFoundAt(tokenI); while ((opLvl[tokenI] != -4) || (pl[tokenI] != pLvl)) { if (tokenI == (map.size() - 1)) { OStringStream description; description << "Can't find closing parenthesis for " << "pow() function."; fatalParseError ( index, tl, powFoundAt, tokenI, "equationReader::removePowExponents", description ); } tokenI++; } const label closeFoundAt(tokenI); // Ignore if the exponent is only 1 token if ((closeFoundAt - commaFoundAt) > 2) { // Now create sub-equation OStringStream subEqnStream; for ( label subTokenI(commaFoundAt + 1); subTokenI < closeFoundAt; subTokenI++ ) { if ( tl[subTokenI].isPunctuation() && (tl[subTokenI].pToken() == token::COLON)) { subEqnStream << "^"; } else { subEqnStream << tl[subTokenI]; } } string subEqnRawText(subEqnStream.str()); const equation& eqn(operator[](index)); equation subEqn ( eqn.name() + "_powExponent_" + name(powFoundAt), subEqnRawText, eqn.overrideDimensions(), eqn.changeDimensions() ); bool eqnCreated(false); for (label eqnI(0); eqnI < size(); eqnI++) { const equation& eqnTest(operator[](eqnI)); if (eqnTest.name() == subEqn.name()) { clearEquation(eqnI); eqnTest.setRawText(subEqn.rawText()); eqnTest.setOverrideDimensions ( subEqn.overrideDimensions() ); eqnTest.setChangeDimensions ( eqnTest.changeDimensions() ); eqnCreated = true; } } if (!eqnCreated) { createEquation(subEqn); } // Change commaFoundAt + 1 entry to reflect new subEquation // reference tl[commaFoundAt + 1] = token(subEqn.name()); map.set ( commaFoundAt + 1, new equationOperation(findSource(subEqn.name())) ); opLvl[commaFoundAt + 1] = 0; pl[commaFoundAt + 1] = pl[commaFoundAt]; // Remove the subEquation from tl, map, opLvl and pl label tokensRemoved(closeFoundAt - (commaFoundAt + 2)); label newSize(map.size() - tokensRemoved); for ( label subTokenI(commaFoundAt + 2); subTokenI < newSize; subTokenI++ ) { tl[subTokenI] = tl[subTokenI + tokensRemoved]; map[subTokenI] = map[subTokenI + tokensRemoved]; opLvl[subTokenI] = opLvl[subTokenI + tokensRemoved]; pl[subTokenI] = pl[subTokenI + tokensRemoved]; } tl.setSize(newSize); map.setSize(newSize); opLvl.setSize(newSize); pl.setSize(newSize); } } tokenI++; } }
void Foam::meshRefinement::findNearest ( const labelList& meshFaces, List<pointIndexHit>& nearestInfo, labelList& nearestSurface, labelList& nearestRegion, vectorField& nearestNormal ) const { pointField fc(meshFaces.size()); forAll(meshFaces, i) { fc[i] = mesh_.faceCentres()[meshFaces[i]]; } const labelList allSurfaces(identity(surfaces_.surfaces().size())); surfaces_.findNearest ( allSurfaces, fc, scalarField(fc.size(), sqr(GREAT)), // sqr of attraction nearestSurface, nearestInfo ); // Do normal testing per surface. nearestNormal.setSize(nearestInfo.size()); nearestRegion.setSize(nearestInfo.size()); forAll(allSurfaces, surfI) { DynamicList<pointIndexHit> localHits; forAll(nearestSurface, i) { if (nearestSurface[i] == surfI) { localHits.append(nearestInfo[i]); } } label geomI = surfaces_.surfaces()[surfI]; pointField localNormals; surfaces_.geometry()[geomI].getNormal(localHits, localNormals); labelList localRegion; surfaces_.geometry()[geomI].getRegion(localHits, localRegion); label localI = 0; forAll(nearestSurface, i) { if (nearestSurface[i] == surfI) { nearestNormal[i] = localNormals[localI]; nearestRegion[i] = localRegion[localI]; localI++; } } }
void getCellTable(const fvMesh & mesh) { cellTableMap_.clear(); cellTableId_.setSize(mesh.nCells(), 1); IOdictionary cellTableDict ( IOobject ( "cellTable", "constant", mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false ) ); volScalarField volField ( IOobject ( "cellTableId", mesh.time().timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false ), mesh, dimensionedScalar("cellTableId", dimless, 1.0) ); // get cellTableId information from the volScalarField if possible if (volField.headerOk()) { const scalarField & field = volField.internalField(); forAll(field, cellI) { cellTableId_[cellI] = static_cast<int>(field[cellI]); } if (cellTableDict.headerOk()) { // convert dictionary to map wordList toc = cellTableDict.toc(); forAll(toc, i) { word keyword = toc[i]; if (!cellTableDict.isDict(keyword)) continue; const dictionary & dict = cellTableDict.subDict(keyword); if (dict.found("Id") && dict.found("MaterialType")) { label Id; dict["Id"] >> Id; dict["MaterialType"] >> keyword; if (keyword == "fluid") { cellTableMap_.insert(Id, 1); } else if (keyword == "solid") { cellTableMap_.insert(Id, 2); } } }
bool Foam::mergePoints ( const UList<point>& points, const scalar mergeTol, const bool verbose, labelList& pointMap, List<point>& newPoints, const point& origin ) { point compareOrigin = origin; if (origin == point(VGREAT, VGREAT, VGREAT)) { if (points.size()) { compareOrigin = sum(points)/points.size(); } } // Create a old to new point mapping array pointMap.setSize(points.size()); pointMap = -1; // Storage for merged points newPoints.setSize(points.size()); if (points.empty()) { return false; } const scalar mergeTolSqr = sqr(mergeTol); // Sort points by magSqr SortableList<scalar> sortedMagSqr(magSqr(points - compareOrigin)); bool hasMerged = false; label newPointI = 0; // Handle 0th point separately (is always unique) label pointI = sortedMagSqr.indices()[0]; pointMap[pointI] = newPointI; newPoints[newPointI++] = points[pointI]; for (label sortI = 1; sortI < sortedMagSqr.size(); sortI++) { // Get original point index label pointI = sortedMagSqr.indices()[sortI]; // Compare to previous points to find equal one. label equalPointI = -1; for ( label prevSortI = sortI - 1; prevSortI >= 0 && mag ( sortedMagSqr[prevSortI] - sortedMagSqr[sortI] ) <= mergeTolSqr; prevSortI-- ) { label prevPointI = sortedMagSqr.indices()[prevSortI]; if (magSqr(points[pointI] - points[prevPointI]) <= mergeTolSqr) { // Found match. equalPointI = prevPointI; break; } } if (equalPointI != -1) { // Same coordinate as equalPointI. Map to same new point. pointMap[pointI] = pointMap[equalPointI]; hasMerged = true; if (verbose) { Pout<< "Foam::mergePoints : Merging points " << pointI << " and " << equalPointI << " with coordinates:" << points[pointI] << " and " << points[equalPointI] << endl; } } else { // Differs. Store new point. pointMap[pointI] = newPointI; newPoints[newPointI++] = points[pointI]; } } newPoints.setSize(newPointI); return hasMerged; }
void Foam::meshRefinement::snapToSurface ( labelList& pointSurfaceRegion, labelList& edgeSurfaceRegion, scalarField& edgeWeight ) { const edgeList& edges = mesh_.edges(); const pointField& points = mesh_.points(); pointSurfaceRegion.setSize(points.size()); pointSurfaceRegion = -1; edgeSurfaceRegion.setSize(edges.size()); edgeSurfaceRegion = -1; edgeWeight.setSize(edges.size()); edgeWeight = -GREAT; // Do test for intersections // ~~~~~~~~~~~~~~~~~~~~~~~~~ labelList surface1; List<pointIndexHit> hit1; labelList region1; //vectorField normal1; labelList surface2; List<pointIndexHit> hit2; labelList region2; //vectorField normal2; { vectorField start(edges.size()); vectorField end(edges.size()); forAll(edges, edgei) { const edge& e = edges[edgei]; start[edgei] = points[e[0]]; end[edgei] = points[e[1]]; } surfaces_.findNearestIntersection ( //labelList(1, 0), //identity(surfaces_.surfaces().size()), identity(surfaces_.surfaces().size()), start, end, surface1, hit1, region1, //normal1, surface2, hit2, region2 //normal2 ); } // Adjust location // ~~~~~~~~~~~~~~~ pointField newPoints(points); label nAdjusted = 0; const labelListList& pointEdges = mesh_.pointEdges(); forAll(pointEdges, pointi) { const point& pt = points[pointi]; const labelList& pEdges = pointEdges[pointi]; // Get the nearest intersection label minEdgei = -1; scalar minFraction = 0.5; // Harpoon 0.25; // Samm? forAll(pEdges, pEdgei) { label edgei = pEdges[pEdgei]; if (hit1[edgei].hit()) { const point& hitPt = hit1[edgei].hitPoint(); const edge& e = edges[edgei]; label otherPointi = e.otherVertex(pointi); const point& otherPt = points[otherPointi]; vector eVec(otherPt-pt); scalar f = eVec&(hitPt-pt)/magSqr(eVec); if (f < minFraction) { minEdgei = edgei; minFraction = f; } } } if (minEdgei != -1 && minFraction >= 0.01) { // Move point to intersection with minEdgei if (pointSurfaceRegion[pointi] == -1) { pointSurfaceRegion[pointi] = surfaces_.globalRegion ( surface1[minEdgei], region1[minEdgei] ); newPoints[pointi] = hit1[minEdgei].hitPoint(); nAdjusted++; } } }