void Foam::displacementMotionSolver::updateMesh(const mapPolyMesh& mpm) { // pointMesh already updates pointFields motionSolver::updateMesh(mpm); // Map points0_. Bit special since we somehow have to come up with // a sensible points0 position for introduced points. // Find out scaling between points0 and current points // Get the new points either from the map or the mesh const pointgpuField& points = ( mpm.hasMotionPoints() ? mpm.preMotionPoints() : mesh().points() ); // Note: boundBox does reduce const vector span0 = boundBox(points0_).span(); const vector span = boundBox(points).span(); vector scaleFactors(cmptDivide(span0, span)); pointField newPoints0(mpm.pointMap().size()); forAll(newPoints0, pointI) { label oldPointI = mpm.pointMap()[pointI]; if (oldPointI >= 0) { label masterPointI = mpm.reversePointMap()[oldPointI]; if (masterPointI == pointI) { newPoints0[pointI] = points0_[oldPointI]; } else { // New point - assume motion is scaling newPoints0[pointI] = points0_[oldPointI] + cmptMultiply ( scaleFactors, points[pointI] - points[masterPointI] ); } } else { FatalErrorIn ( "displacementMotionSolver::updateMesh" "(const mapPolyMesh&)" ) << "Cannot determine co-ordinates of introduced vertices." << " New vertex " << pointI << " at co-ordinate " << points[pointI] << exit(FatalError); } }
Foam::boundBox Foam::tetrahedron<Point, PointRef>::bounds() const { return boundBox ( min(a(), min(b(), min(c(), d()))), max(a(), max(b(), max(c(), d()))) ); }
void Foam::polyMesh::resetPrimitives ( const Xfer<pointField>& pts, const Xfer<faceList>& fcs, const Xfer<labelList>& own, const Xfer<labelList>& nei, const labelList& patchSizes, const labelList& patchStarts, const bool validBoundary ) { // Clear addressing. Keep geometric props for mapping. clearAddressing(); // Take over new primitive data. // Optimized to avoid overwriting data at all if (&pts) { allPoints_.transfer(pts()); // Recalculate bounds with all points. HJ, 17/Oct/2008 // ... if points have change. HJ, 19/Aug/2010 bounds_ = boundBox(allPoints_, validBoundary); } if (&fcs) { allFaces_.transfer(fcs()); // Faces will be reset in initMesh(), using size of owner list } if (&own) { owner_.transfer(own()); } if (&nei) { neighbour_.transfer(nei()); } // Reset patch sizes and starts forAll (boundary_, patchI) { boundary_[patchI] = polyPatch ( boundary_[patchI].name(), patchSizes[patchI], patchStarts[patchI], patchI, boundary_ ); }
void Foam::polyMesh::resetPrimitives ( const Xfer<pointField>& points, const Xfer<faceList>& faces, const Xfer<labelList>& owner, const Xfer<labelList>& neighbour, const labelList& patchSizes, const labelList& patchStarts, const bool validBoundary ) { // Clear addressing. Keep geometric props and updateable props for mapping. clearAddressing(true); // Take over new primitive data. // Optimized to avoid overwriting data at all if (notNull(points)) { points_.transfer(points()); bounds_ = boundBox(points_, validBoundary); } if (notNull(faces)) { faces_.transfer(faces()); } if (notNull(owner)) { owner_.transfer(owner()); } if (notNull(neighbour)) { neighbour_.transfer(neighbour()); } // Reset patch sizes and starts forAll(boundary_, patchI) { boundary_[patchI] = polyPatch ( boundary_[patchI], boundary_, patchI, patchSizes[patchI], patchStarts[patchI] ); }
Foam::searchableSphere::searchableSphere ( const IOobject& io, const dictionary& dict ) : searchableSurface(io), centre_(dict.lookup("centre")), radius_(readScalar(dict.lookup("radius"))) { bounds() = boundBox ( centre_ - radius_*vector::one, centre_ + radius_*vector::one ); }
Foam::searchableSphere::searchableSphere ( const IOobject& io, const point& centre, const scalar radius ) : searchableSurface(io), centre_(centre), radius_(radius) { bounds() = boundBox ( centre_ - radius_*vector::one, centre_ + radius_*vector::one ); }
Foam::boundBox Foam::searchableCylinder::calcBounds() const { // Adapted from // http://www.gamedev.net/community/forums // /topic.asp?topic_id=338522&forum_id=20&gforum_id=0 // Let cylinder have end points A,B and radius r, // Bounds in direction X (same for Y and Z) can be found as: // Let A.X<B.X (otherwise swap points) // Good approximate lowest bound is A.X-r and highest is B.X+r (precise for // capsule). At worst, in one direction it can be larger than needed by 2*r. // Accurate bounds for cylinder is // A.X-kx*r, B.X+kx*r // where // kx=sqrt(((A.Y-B.Y)^2+(A.Z-B.Z)^2)/((A.X-B.X)^2+(A.Y-B.Y)^2+(A.Z-B.Z)^2)) // similar thing for Y and Z // (i.e. // ky=sqrt(((A.X-B.X)^2+(A.Z-B.Z)^2)/((A.X-B.X)^2+(A.Y-B.Y)^2+(A.Z-B.Z)^2)) // kz=sqrt(((A.X-B.X)^2+(A.Y-B.Y)^2)/((A.X-B.X)^2+(A.Y-B.Y)^2+(A.Z-B.Z)^2)) // ) // How derived: geometric reasoning. Bounds of cylinder is same as for 2 // circles centered on A and B. This sqrt thingy gives sine of angle between // axis and direction, used to find projection of radius. vector kr ( sqrt(sqr(unitDir_.y()) + sqr(unitDir_.z())), sqrt(sqr(unitDir_.x()) + sqr(unitDir_.z())), sqrt(sqr(unitDir_.x()) + sqr(unitDir_.y())) ); kr *= radius_; point min = point1_ - kr; point max = point1_ + kr; min = ::Foam::min(min, point2_ - kr); max = ::Foam::max(max, point2_ + kr); return boundBox(min, max); }
Foam::boundBox Foam::toroidalCS::spanBounds() const { return boundBox ( vector ( 0, ( inDegrees_ ? -180.0 : -mathematicalConstant::pi ), ( inDegrees_ ? -180.0 : -mathematicalConstant::pi ) ), vector ( GREAT, ( inDegrees_ ? 180.0 : mathematicalConstant::pi ), ( inDegrees_ ? 180.0 : mathematicalConstant::pi ) ) ); }
Foam::boundBox Foam::parabolicCylindricalCS::spanBounds() const { return boundBox ( vector ( 0, ( inDegrees_ ? -180.0 : -mathematicalConstant::pi ), -GREAT ), vector ( GREAT, ( inDegrees_ ? 180.0 : mathematicalConstant::pi ), GREAT ) ); }
Foam::searchablePlate::searchablePlate ( const IOobject& io, const dictionary& dict ) : searchableSurface(io), origin_(dict.lookup("origin")), span_(dict.lookup("span")), normalDir_(calcNormal(span_)) { if (debug) { InfoInFunction << " origin:" << origin_ << " origin+span:" << origin_+span_ << " normal:" << vector::componentNames[normalDir_] << endl; } bounds() = boundBox(origin_, origin_ + span_); }
Foam::searchablePlate::searchablePlate ( const IOobject& io, const point& origin, const vector& span ) : searchableSurface(io), origin_(origin), span_(span), normalDir_(calcNormal(span_)) { if (debug) { InfoInFunction << " origin:" << origin_ << " origin+span:" << origin_+span_ << " normal:" << vector::componentNames[normalDir_] << endl; } bounds() = boundBox(origin_, origin_ + span_); }
Foam::binaryOperationSearchableSurface::binaryOperationSearchableSurface ( const IOobject& io, const dictionary& dict ) : searchableSurface(io), aName_(dict.lookupOrDefault<word>("aName","A")), bName_(dict.lookupOrDefault<word>("bName","B")), a_( searchableSurface::New ( word(dict.subDict("a").lookup("type")), IOobject( name()+"_"+word(dict.lookup("type"))+"_"+aName_, io.instance(), io.db(), io.readOpt(), io.writeOpt() ), dict.subDict("a") ) ), b_( searchableSurface::New ( word(dict.subDict("b").lookup("type")), IOobject( name()+"_"+word(dict.lookup("type"))+"_"+bName_, io.instance(), io.db(), io.readOpt(), io.writeOpt() ), dict.subDict("b") ) ), nrARegions_( a().regions().size() ), nrBRegions_( b().regions().size() ) { if(aName_==bName_) { FatalErrorIn("binaryOperationSearchableSurface::binaryOperationSearchableSurface") << "'aName' and 'bName' have the same value " << aName_ << " for " << name() << endl << exit(FatalError); } if(regions().size()!=size()) { FatalErrorIn("binaryOperationSearchableSurface::binaryOperationSearchableSurface") << "Number of regions " << regions().size() << " not equal to size " << size() << nl << "Regions: " << regions() << endl << exit(FatalError); } #ifdef FOAM_SEARCHABLE_SURF_HAS_BOUND_METHOD pointField pts(4); pts[0]=a().bounds().min(); pts[1]=a().bounds().max(); pts[2]=b().bounds().min(); pts[3]=b().bounds().max(); bounds()=boundBox(pts); #endif }
Foam::scalar Foam::edgeStats::minLen(Ostream& os) const { label nX = 0; label nY = 0; label nZ = 0; scalar minX = GREAT; scalar maxX = -GREAT; vector x(1, 0, 0); scalar minY = GREAT; scalar maxY = -GREAT; vector y(0, 1, 0); scalar minZ = GREAT; scalar maxZ = -GREAT; vector z(0, 0, 1); scalar minOther = GREAT; scalar maxOther = -GREAT; const edgeList& edges = mesh_.edges(); forAll(edges, edgeI) { const edge& e = edges[edgeI]; vector eVec(e.vec(mesh_.points())); scalar eMag = mag(eVec); eVec /= eMag; if (mag(eVec & x) > 1-edgeTol_) { minX = min(minX, eMag); maxX = max(maxX, eMag); nX++; } else if (mag(eVec & y) > 1-edgeTol_) { minY = min(minY, eMag); maxY = max(maxY, eMag); nY++; } else if (mag(eVec & z) > 1-edgeTol_) { minZ = min(minZ, eMag); maxZ = max(maxZ, eMag); nZ++; } else { minOther = min(minOther, eMag); maxOther = max(maxOther, eMag); } } os << "Mesh bounding box:" << boundBox(mesh_.points()) << nl << nl << "Mesh edge statistics:" << nl << " x aligned : number:" << nX << "\tminLen:" << minX << "\tmaxLen:" << maxX << nl << " y aligned : number:" << nY << "\tminLen:" << minY << "\tmaxLen:" << maxY << nl << " z aligned : number:" << nZ << "\tminLen:" << minZ << "\tmaxLen:" << maxZ << nl << " other : number:" << mesh_.nEdges() - nX - nY - nZ << "\tminLen:" << minOther << "\tmaxLen:" << maxOther << nl << endl; if (normalDir_ == 0) { return min(minY, min(minZ, minOther)); } else if (normalDir_ == 1) { return min(minX, min(minZ, minOther)); } else if (normalDir_ == 2) { return min(minX, min(minY, minOther)); } else { return min(minX, min(minY, min(minZ, minOther))); } }
Foam::autoPtr<Foam::mapDistribute> Foam::meshToMeshNew::calcProcMap ( const polyMesh& src, const polyMesh& tgt ) const { // get decomposition of cells on src mesh List<boundBox> procBb(Pstream::nProcs()); if (src.nCells() > 0) { // bounding box for my mesh - do not parallel reduce procBb[Pstream::myProcNo()] = boundBox(src.points(), false); // slightly increase size of bounding boxes to allow for cases where // bounding boxes are perfectly alligned procBb[Pstream::myProcNo()].inflate(0.01); } else { procBb[Pstream::myProcNo()] = boundBox(); } Pstream::gatherList(procBb); Pstream::scatterList(procBb); if (debug) { Info<< "Determining extent of src mesh per processor:" << nl << "\tproc\tbb" << endl; forAll(procBb, procI) { Info<< '\t' << procI << '\t' << procBb[procI] << endl; } } // determine which cells of tgt mesh overlaps src mesh per proc const cellList& cells = tgt.cells(); const faceList& faces = tgt.faces(); const pointField& points = tgt.points(); labelListList sendMap; { // per processor indices into all segments to send List<DynamicList<label> > dynSendMap(Pstream::nProcs()); label iniSize = floor(tgt.nCells()/Pstream::nProcs()); forAll(dynSendMap, procI) { dynSendMap[procI].setCapacity(iniSize); } // work array - whether src processor bb overlaps the tgt cell bounds boolList procBbOverlaps(Pstream::nProcs()); forAll(cells, cellI) { const cell& c = cells[cellI]; // determine bounding box of tgt cell boundBox cellBb(point::max, point::min); forAll(c, faceI) { const face& f = faces[c[faceI]]; forAll(f, fp) { cellBb.min() = min(cellBb.min(), points[f[fp]]); cellBb.max() = max(cellBb.max(), points[f[fp]]); } } // find the overlapping tgt cells on each src processor (void)calcOverlappingProcs(procBb, cellBb, procBbOverlaps); forAll(procBbOverlaps, procI) { if (procBbOverlaps[procI]) { dynSendMap[procI].append(cellI); } } }
void Foam::edgeMesh::writeStats(Ostream& os) const { os << "points : " << points().size() << nl; os << "edges : " << edges().size() << nl; os << "boundingBox : " << boundBox(this->points()) << endl; }
Foam::searchableExtrudedCircle::searchableExtrudedCircle ( const IOobject& io, const dictionary& dict ) : searchableSurface(io), eMeshPtr_ ( edgeMesh::New ( IOobject ( dict.lookup("file"), // name io.time().constant(), // instance "geometry", // local io.time(), // registry IOobject::MUST_READ, IOobject::NO_WRITE, false ).objectPath() ) ), radius_(readScalar(dict.lookup("radius"))) { const edgeMesh& eMesh = eMeshPtr_(); const pointField& points = eMesh.points(); const edgeList& edges = eMesh.edges(); bounds() = boundBox(points, false); vector halfSpan(0.5*bounds().span()); point ctr(bounds().midpoint()); bounds().min() = ctr - mag(halfSpan)*vector(1, 1, 1); bounds().max() = ctr + mag(halfSpan)*vector(1, 1, 1); // Calculate bb of all points treeBoundBox bb(bounds()); // Slightly extended bb. Slightly off-centred just so on symmetric // geometry there are less face/edge aligned items. bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL); edgeTree_.reset ( new indexedOctree<treeDataEdge> ( treeDataEdge ( false, // do not cache bb edges, points, identity(edges.size()) ), bb, // overall search domain 8, // maxLevel 10, // leafsize 3.0 // duplicity ) ); }