ENH: support arc edge specification with origin point

- The arc will frequently enclose an angle less than 180 degrees.
  For the case, it is possible to define the arc by its endpoints
  and its centre (origin) point. For example,

      arc 0 1 origin (0 0 0);

  When defined in the way, any discrepancy in the arc radius for the
  endpoints is resolved by adjusting the origin to ensure that the
  average radius is satisfied.

  It is also possible to specify a \em flatness factor as a multiplier
  of the radius. For example,

      arc 0 1 origin 1.1 (0 0 0);

ENH: minor code cleanup for block edges

ENH: expose point appending as polyList::concat
This commit is contained in:
Mark Olesen
2020-10-05 12:36:19 +02:00
parent 8939a55653
commit 1d08ed9be2
26 changed files with 575 additions and 299 deletions

View File

@ -134,7 +134,7 @@ Foam::point Foam::BSpline::position
Foam::scalar Foam::BSpline::length() const
{
NotImplemented;
return 1.0;
return 1;
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -77,21 +78,12 @@ class BSpline
:
public polyLine
{
// Private Member Functions
//- No copy construct
BSpline(const BSpline&) = delete;
//- No copy assignment
void operator=(const BSpline&) = delete;
public:
// Constructors
//- Construct from components
BSpline
explicit BSpline
(
const pointField& knots,
const bool notImplementedClosed = false
@ -100,15 +92,16 @@ public:
// Member Functions
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the global curve parameter
// 0 <= lambda <= 1
point position(const scalar lambda) const;
//- Return the point position corresponding to the local parameter
// 0 <= lambda <= 1 on the given segment
//- The point position corresponding to the local lambda (0-1)
//- on the given segment
point position(const label segment, const scalar lambda) const;
//- Return the length of the curve
//- The length of the curve
// \note NotImplemented
scalar length() const;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,9 +27,9 @@ License
\*---------------------------------------------------------------------------*/
#include "BSplineEdge.H"
#include "polyLine.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
@ -59,7 +59,10 @@ Foam::blockEdges::BSplineEdge::BSplineEdge
)
:
blockEdge(points, start, end),
BSpline(appendEndPoints(points, start, end, internalPoints))
BSpline
(
polyLine::concat(points[start_], internalPoints, points[end_])
)
{}
@ -73,13 +76,16 @@ Foam::blockEdges::BSplineEdge::BSplineEdge
)
:
blockEdge(dict, index, points, is),
BSpline(appendEndPoints(points, start_, end_, pointField(is)))
BSpline
(
polyLine::concat(points[start_], pointField(is), points[end_])
)
{
token t(is);
is.putBack(t);
token tok(is);
is.putBack(tok);
// discard unused start/end tangents
if (t == token::BEGIN_LIST)
// Discard unused start/end tangents
if (tok == token::BEGIN_LIST)
{
vector tangent0Ignored(is);
vector tangent1Ignored(is);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2014-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -77,20 +77,20 @@ public:
//- Construct from components
BSplineEdge
(
const pointField&,
const label start,
const label end,
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end, //!< End point in referenced point field
const pointField& internalPoints
);
//- Construct from Istream, setting pointsList
//- Construct from Istream and point field.
BSplineEdge
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField&,
Istream&
const pointField& points, //!< Referenced point field
Istream& is
);
@ -100,11 +100,12 @@ public:
// Member Functions
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
virtual point position(const scalar) const;
//- Return the length of the spline curve (not implemented)
//- The length of the spline curve
// \note NotImplemented
virtual scalar length() const;
};

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -43,10 +44,15 @@ namespace blockEdges
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::coordSystem::cylindrical Foam::blockEdges::arcEdge::calcAngle()
void Foam::blockEdges::arcEdge::calcFromMidPoint
(
const point& p1,
const point& p3,
const point& p2
)
{
const vector a = p2_ - p1_;
const vector b = p3_ - p1_;
const vector a = p2 - p1;
const vector b = p3 - p1;
// Find centre of arcEdge
const scalar asqr = a & a;
@ -55,7 +61,7 @@ Foam::coordSystem::cylindrical Foam::blockEdges::arcEdge::calcAngle()
const scalar denom = asqr*bsqr - adotb*adotb;
if (mag(denom) < VSMALL)
if (mag(denom) < ROOTVSMALL)
{
FatalErrorInFunction
<< denom
@ -64,44 +70,120 @@ Foam::coordSystem::cylindrical Foam::blockEdges::arcEdge::calcAngle()
const scalar fact = 0.5*(bsqr - adotb)/denom;
point centre = 0.5*a + fact*((a ^ b) ^ a);
const point centre = p1 + 0.5*a + fact*((a ^ b) ^ a);
centre += p1_;
// Position vectors from centre
const vector r1(p1 - centre);
const vector r2(p2 - centre);
const vector r3(p3 - centre);
// Find position vectors w.r.t. the arcEdge centre
const vector r1(p1_ - centre);
const vector r2(p2_ - centre);
const vector r3(p3_ - centre);
const scalar mag1(mag(r1));
const scalar mag3(mag(r3));
// Find angle (in degrees)
angle_ = radToDeg(acos((r3 & r1)/(mag(r3) * mag(r1))));
vector arcAxis(r1 ^ r3);
// The radius from r1 and from r3 will be identical
radius_ = mag(r3);
// Determine the angle
angle_ = acos((r1 & r3)/(mag1*mag3));
// Check if the vectors define an exterior or an interior arcEdge
if (((r1 ^ r2) & (r1 ^ r3)) < 0.0)
{
angle_ = 360.0 - angle_;
angle_ = constant::mathematical::twoPi - angle_;
}
vector arcAxis;
if (angle_ <= 180.0)
if (angle_ <= constant::mathematical::pi)
{
arcAxis = r1 ^ r3;
if (mag(arcAxis)/(mag(r1)*mag(r3)) < 0.001)
if (mag(arcAxis)/(mag1*mag3) < 0.001)
{
arcAxis = r1 ^ r2;
}
}
else
{
arcAxis = r3 ^ r1;
arcAxis = -arcAxis;
}
radius_ = mag(r3);
// Corresponding local cylindrical coordinate system
cs_ = coordSystem::cylindrical(centre, arcAxis, r1);
}
// The corresponding local cylindrical coordinate system (radians)
return coordSystem::cylindrical("arc", centre, arcAxis, r1);
void Foam::blockEdges::arcEdge::calcFromCentre
(
const point& p1,
const point& p3,
const point& centre,
bool adjustCentre,
scalar rMultiplier
)
{
// Position vectors from centre
const vector r1(p1 - centre);
const vector r3(p3 - centre);
const scalar mag1(mag(r1));
const scalar mag3(mag(r3));
const vector chord(p3 - p1);
const vector arcAxis(r1 ^ r3);
// The average radius
radius_ = 0.5*(mag1 + mag3);
// The included angle
angle_ = acos((r1 & r3)/(mag1*mag3));
// TODO? check for 180 degrees (co-linear points)?
bool needsAdjust = false;
if (adjustCentre)
{
needsAdjust = !equal(mag1, mag3);
if (!equal(rMultiplier, 1))
{
// The min radius is constrained by the chord,
// otherwise bad things will happen.
needsAdjust = true;
radius_ *= rMultiplier;
radius_ = max(radius_, (1.001*0.5*mag(chord)));
}
}
if (needsAdjust)
{
// The centre is not equidistant to p1 and p3.
// Use the chord and the arcAxis to determine the vector to
// the midpoint of the chord and adjust the centre along this
// line.
const point newCentre =
(
(0.5 * (p3 + p1)) // mid-chord point
+ sqrt(sqr(radius_) - 0.25 * magSqr(chord))
* normalised(arcAxis ^ chord) // mid-chord -> centre
);
//// Info<< nl << "Adjust centre. r1=" << mag1 << " r3=" << mag3
//// << " radius=" << radius_ << nl
//// << "angle=" << radToDeg(angle_) << ' '
//// << coordSystem::cylindrical(centre, arcAxis, r1) << nl;
// Recalculate - do attempt to readjust
calcFromCentre(p1, p3, newCentre, false);
}
else
{
// Corresponding local cylindrical coordinate system
cs_ = coordSystem::cylindrical(centre, arcAxis, r1);
}
}
@ -110,17 +192,35 @@ Foam::coordSystem::cylindrical Foam::blockEdges::arcEdge::calcAngle()
Foam::blockEdges::arcEdge::arcEdge
(
const pointField& points,
const point& origin,
const label start,
const label end,
const point& pMid
const label end
)
:
blockEdge(points, start, end),
p1_(points_[start_]),
p2_(pMid),
p3_(points_[end_]),
cs_(calcAngle())
{}
radius_(0),
angle_(0),
cs_()
{
calcFromCentre(points[start_], points[end_], origin);
}
Foam::blockEdges::arcEdge::arcEdge
(
const pointField& points,
const label start,
const label end,
const point& midPoint
)
:
blockEdge(points, start, end),
radius_(0),
angle_(0),
cs_()
{
calcFromMidPoint(points[start_], points[end_], midPoint);
}
Foam::blockEdges::arcEdge::arcEdge
@ -133,41 +233,82 @@ Foam::blockEdges::arcEdge::arcEdge
)
:
blockEdge(dict, index, points, is),
p1_(points_[start_]),
p2_(is),
p3_(points_[end_]),
cs_(calcAngle())
{}
radius_(0),
angle_(0),
cs_()
{
point p;
token tok(is);
if (tok.isWord())
{
// Can be
// - origin (0 0 0)
// - origin 1.2 (0 0 0)
scalar rMultiplier = 1;
is >> tok;
if (tok.isNumber())
{
rMultiplier = tok.number();
}
else
{
is.putBack(tok);
}
is >> p; // The origin (centre)
calcFromCentre(points_[start_], points_[end_], p, true, rMultiplier);
}
else
{
is.putBack(tok);
is >> p; // A mid-point
calcFromMidPoint(points_[start_], points_[end_], p);
}
// Debug information
#if 0
Info<< "arc " << start_ << ' ' << end_
<< ' ' << position(0.5) << ' ' << cs_
// << " radius=" << radius_ << " angle=" << radToDeg(angle_)
<< nl;
#endif
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::point Foam::blockEdges::arcEdge::position(const scalar lambda) const
{
#ifdef FULLDEBUG
if (lambda < -SMALL || lambda > 1 + SMALL)
{
FatalErrorInFunction
<< "Parameter out of range, lambda = " << lambda
<< abort(FatalError);
WarningInFunction
<< "Parameter out of range, lambda = " << lambda << nl;
}
#endif
if (lambda < SMALL)
{
return p1_;
return points_[start_];
}
else if (lambda > 1 - SMALL)
else if (lambda >= 1 - SMALL)
{
return p3_;
return points_[end_];
}
// The angle is degrees, the coordinate system in radians
return cs_.globalPosition(vector(radius_, degToRad(lambda*angle_), 0));
return cs_.globalPosition(vector(radius_, (lambda*angle_), 0));
}
Foam::scalar Foam::blockEdges::arcEdge::length() const
Foam::scalar Foam::blockEdges::arcEdge::length() const noexcept
{
return degToRad(radius_*angle_);
return (radius_*angle_);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,7 +28,32 @@ Class
Foam::blockEdges::arcEdge
Description
Defines the arcEdge of a circle in terms of 3 points on its circumference
A blockEdge defined as an arc of a circle.
The arc is normally defined by its endpoints and a point on
its circumference, typically a midpoint. For example,
\verbatim
points ((1 0 0) (0 1 0));
arc 0 1 (0.707107 0.707107 0);
\endverbatim
The arc can enclose an angle greater than 0 and less than 360 degrees.
The arc will frequently enclose an angle less than 180 degrees.
For the case, it is possible to define the arc by its endpoints and its
centre (origin) point. For example,
\verbatim
arc 0 1 origin (0 0 0);
\endverbatim
When defined in the way, any discrepancy in the arc radius for the
endpoints is resolved by adjusting the origin to ensure that the average
radius is satisfied.
It is also possible to define a \em flatness factor as a multiplier of
the calculated radius. For example,
\verbatim
arc 0 1 origin 1.1 (0 0 0);
\endverbatim
SourceFiles
arcEdge.C
@ -56,26 +81,41 @@ class arcEdge
:
public blockEdge
{
// Private data
// Begin, mid, end points
point p1_, p2_, p3_;
//- The arc angle (in degrees)
scalar angle_;
// Private Data
//- The arc radius
scalar radius_;
//- The arc angle (radians)
scalar angle_;
//- The local cylindrical coordinate system
coordSystem::cylindrical cs_;
// Private Member Functions
//- Calculate the angle, radius and axis
// \return the cylindrical coordinate system
coordSystem::cylindrical calcAngle();
//- Calculate angle, radius, cylindrical coordinate system
//- from end points and the given point on the circumference
void calcFromMidPoint
(
const point& p1, //!< Start point
const point& p3, //!< End point
const point& p2 //!< Point on circumference
);
//- Calculate angle, radius, cylindrical coordinate system
//- from end points and the given origin.
// Optionally adjust centre to accommodate deviations in the
// effective radius to the end-points
void calcFromCentre
(
const point& p1, //!< Start point
const point& p3, //!< End point
const point& centre, //!< Centre
bool adjustCentre = false, //!< Adjust centre
scalar rMultiplier = 1 //!< Adjust radius by this factor
);
//- No copy construct
arcEdge(const arcEdge&) = delete;
@ -92,23 +132,34 @@ public:
// Constructors
//- Construct from components
//- Construct from components, given the origin of the circle
arcEdge
(
const pointField& points,
const label start,
const label end,
const point& pMid
const pointField& points, //!< Referenced point field
const point& origin, //!< The origin of the circle
const label start, //!< Start point in referenced point field
const label end //!< End point in referenced point field
);
//- Construct from Istream setting pointsList
//- Construct from components, using a point on the circumference
arcEdge
(
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end, //!< End point in referenced point field
const point& midPoint //!< A point on the circumference
);
//- Construct from Istream and point field.
// The Istream can specify either a point on the circumference,
// or with a tag to specify the origin.
arcEdge
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField& points,
Istream&
const searchableSurfaces& geometry, // unsed
const pointField& points, //!< Referenced point field
Istream& is
);
@ -122,7 +173,7 @@ public:
point position(const scalar lambda) const;
//- The length of the curve
scalar length() const;
scalar length() const noexcept;
};

View File

@ -26,6 +26,7 @@ License
\*---------------------------------------------------------------------------*/
#include "bezier.H"
#include "polyLine.H"
#include "SubList.H"
#include "addToRunTimeSelectionTable.H"
@ -66,7 +67,10 @@ Foam::blockEdges::bezier::bezier
)
:
blockEdge(dict, index, points, is),
control_(appendEndPoints(points, start_, end_, pointField(is)))
control_
(
polyLine::concat(points[start_], pointField(is), points[end_])
)
{}
@ -94,7 +98,7 @@ Foam::point Foam::blockEdges::bezier::position(const scalar lambda) const
Foam::scalar Foam::blockEdges::bezier::length() const
{
NotImplemented;
return 1.0;
return 1;
}

View File

@ -63,7 +63,7 @@ class bezier
:
public blockEdge
{
private:
// Private Data
//- Control points
pointField control_;
@ -89,20 +89,20 @@ public:
//- Construct from components
bezier
(
const pointField& points,
const label start,
const label end,
const pointField& control
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end, //!< End point in referenced point field
const pointField& control //!< The control points
);
//- Construct from Istream
//- Construct from Istream and point field.
bezier
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField&,
Istream&
const pointField& points, //!< Referenced point field
Istream& is
);
@ -117,6 +117,7 @@ public:
point position(const scalar lambda) const;
//- Return the length of the curve
// \not NotImplemented
scalar length() const;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,6 +28,7 @@ License
#include "blockEdge.H"
#include "blockVertex.H"
#include "polyLine.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -104,32 +105,22 @@ Foam::autoPtr<Foam::blockEdge> Foam::blockEdge::New
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::pointField Foam::blockEdge::appendEndPoints
(
const pointField& points,
const pointField& pts,
const label start,
const label end,
const pointField& otherKnots
const pointField& intermediate
)
{
pointField allKnots(otherKnots.size() + 2);
// Start/end knots
allKnots[0] = points[start];
allKnots[otherKnots.size() + 1] = points[end];
// Intermediate knots
forAll(otherKnots, knotI)
{
allKnots[knotI+1] = otherKnots[knotI];
}
return allKnots;
return pointField(polyLine::concat(pts[start], intermediate, pts[end]));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::pointField>
Foam::blockEdge::position(const scalarList& lambdas) const
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,6 +24,12 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Namespace
Foam::blockEdges
Description
A namespace for various blockEdge types.
Class
Foam::blockEdge
@ -46,13 +52,10 @@ SourceFiles
namespace Foam
{
// Forward declaration of friend functions and operators
// Forward Declarations
class blockEdge;
Ostream& operator<<(Ostream&, const blockEdge&);
/*---------------------------------------------------------------------------*\
Class blockEdge Declaration
\*---------------------------------------------------------------------------*/
@ -61,24 +64,29 @@ class blockEdge
{
protected:
// Protected data
// Protected Data
//- The referenced point field
const pointField& points_;
//- Index of the start point
const label start_;
//- Index of the end point
const label end_;
// Protected Member Functions
//- Return a complete point field by appending the start/end points
// to the given list
//- to the given list
// \deprecated(2020-10) use polyLine::concat
static pointField appendEndPoints
(
const pointField&,
const label start,
const label end,
const pointField& otherKnots
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end, //!< End point in referenced point field
const pointField& intermediate //!< Intermediate points (knots)
);
@ -110,18 +118,18 @@ public:
//- Construct from components
blockEdge
(
const pointField& points,
const label start,
const label end
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end //!< End point in referenced point field
);
//- Construct from Istream setting pointsList
//- Construct from Istream and point field.
blockEdge
(
const dictionary& dict,
const label index,
const pointField&,
Istream&
const pointField& points, //!< Referenced point field
Istream& is
);
//- Clone function
@ -133,8 +141,8 @@ public:
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField&,
Istream&
const pointField& points,
Istream& is
);
//- Class used for the read-construction of
@ -174,10 +182,10 @@ public:
// Member Functions
//- Return label of start point
//- Index of start point
inline label start() const;
//- Return label of end point
//- Index of end point
inline label end() const;
//- Compare the given start and end points with this curve
@ -201,22 +209,22 @@ public:
// - -1: same edge, but different orientation
inline int compare(const label start, const label end) const;
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
virtual point position(const scalar) const = 0;
//- Return the point positions corresponding to the curve parameters
//- The point positions corresponding to the curve parameters
// 0 <= lambda <= 1
virtual tmp<pointField> position(const scalarList&) const;
//- Return the length of the curve
//- The length of the curve
virtual scalar length() const = 0;
//- Write edge with variable backsubstitution
void write(Ostream&, const dictionary&) const;
// Ostream operator
// Ostream Operator
friend Ostream& operator<<(Ostream&, const blockEdge&);
};

View File

@ -49,10 +49,8 @@ inline int Foam::blockEdge::compare(const label start, const label end) const
{
return -1;
}
else
{
return 0;
}
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,6 +47,7 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class blockEdge;
/*---------------------------------------------------------------------------*\
@ -54,7 +56,7 @@ class blockEdge;
class lineDivide
{
// Private data
// Private Data
pointField points_;
@ -67,18 +69,18 @@ public:
//- Construct from components
lineDivide
(
const blockEdge&,
const label ndiv,
const blockEdge& cedge,
const label nDiv,
const gradingDescriptors& gd = gradingDescriptors()
);
// Member Functions
//- Return the points
//- The points
const pointField& points() const;
//- Return the list of lambda values
//- The list of lambda values
const scalarList& lambdaDivisions() const;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -71,11 +71,21 @@ Foam::blockEdges::lineEdge::lineEdge
Foam::point Foam::blockEdges::lineEdge::position(const scalar lambda) const
{
if (lambda < -SMALL || lambda > 1+SMALL)
#ifdef FULLDEBUG
if (lambda < -SMALL || lambda > 1 + SMALL)
{
FatalErrorInFunction
<< "Parameter out of range, lambda = " << lambda
<< abort(FatalError);
WarningInFunction
<< "Parameter out of range, lambda = " << lambda << nl;
}
#endif
if (lambda < SMALL)
{
return points_[start_];
}
else if (lambda >= 1 - SMALL)
{
return points_[end_];
}
return points_[start_] + lambda * (points_[end_] - points_[start_]);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -51,12 +51,10 @@ namespace blockEdges
Class lineEdge Declaration
\*---------------------------------------------------------------------------*/
class lineEdge
:
public blockEdge
{
public:
//- Runtime type information
@ -66,15 +64,20 @@ public:
// Constructors
//- Construct from components
lineEdge(const pointField&, const label start, const label end);
lineEdge
(
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end //!< End point in referenced point field
);
//- Construct from Istream with a pointField
//- Construct from Istream and point field.
lineEdge
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField&,
const pointField& points, //!< Referenced point field
Istream& is
);
@ -85,11 +88,11 @@ public:
// Member Functions
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
point position(const scalar) const;
//- Return the length of the curve
//- The length of the curve
scalar length() const;
};

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -26,16 +27,41 @@ License
\*---------------------------------------------------------------------------*/
#include "polyLine.H"
#include "SubList.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::tmp<Foam::pointField> Foam::polyLine::concat
(
const point& p0,
const pointField& intermediate,
const point& p1
)
{
auto tresult = tmp<pointField>::New(intermediate.size() + 2);
auto& result = tresult.ref();
// Intermediate points (knots)
SubList<point>(result, intermediate.size(), 1) = intermediate;
// Start/end points (knots)
result.first() = p0;
result.last() = p1;
return tresult;
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::polyLine::calcParam()
{
param_.setSize(points_.size());
lineLength_ = 0;
param_.resize(points_.size());
if (param_.size())
{
param_[0] = 0.0;
param_[0] = 0;
for (label i=1; i < param_.size(); i++)
{
@ -48,23 +74,34 @@ void Foam::polyLine::calcParam()
{
param_[i] /= lineLength_;
}
param_.last() = 1.0;
}
else
{
lineLength_ = 0.0;
param_.last() = 1;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::polyLine::polyLine(const pointField& ps, const bool)
:
points_(ps),
lineLength_(0.0),
param_(0)
lineLength_(0),
param_()
{
calcParam();
}
Foam::polyLine::polyLine
(
const point& start,
const pointField& intermediate,
const point& end,
const bool
)
:
points_(polyLine::concat(start, intermediate, end)),
lineLength_(0),
param_()
{
calcParam();
}
@ -101,19 +138,20 @@ Foam::label Foam::polyLine::localParameter(scalar& lambda) const
// Search table of cumulative distances to find which line-segment
// we are on.
// Check the upper bound.
// Too small to bother with a binary search...
label segmentI = 1;
while (param_[segmentI] < lambda)
label segment = 1;
while (param_[segment] < lambda)
{
segmentI++;
++segment;
}
segmentI--; // We want the corresponding lower bound
--segment; // We want the corresponding lower bound
// The local parameter [0-1] on this line segment
lambda =
(lambda - param_[segmentI])/(param_[segmentI+1] - param_[segmentI]);
(lambda - param_[segment])/(param_[segment+1] - param_[segment]);
return segmentI;
return segment;
}
@ -151,8 +189,8 @@ Foam::point Foam::polyLine::position
return points_.last();
}
const point& p0 = points()[segment];
const point& p1 = points()[segment+1];
const point& p0 = points_[segment];
const point& p1 = points_[segment+1];
// Special cases - no calculation needed
if (mu <= 0.0)
@ -163,11 +201,9 @@ Foam::point Foam::polyLine::position
{
return p1;
}
else
{
// Linear interpolation
return points_[segment] + mu*(p1 - p0);
}
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,26 +53,16 @@ namespace Foam
Class polyLine Declaration
\*---------------------------------------------------------------------------*/
class polyLine
{
// Private Member Functions
//- No copy construct
polyLine(const polyLine&) = delete;
//- No copy assignment
void operator=(const polyLine&) = delete;
protected:
// Protected data
// Protected Data
//- The control points or ends of each segments
pointField points_;
//- The real line length
//- The real (total) line length
scalar lineLength_;
//- The rational (0-1) cumulative parameter value for each point
@ -81,11 +72,11 @@ protected:
// Protected Member Functions
//- Precalculate the rational cumulative parameter value
// and the line-length
//- and the line-length
void calcParam();
//- Return the line segment and the local parameter [0..1]
// corresponding to the global lambda [0..1]
//- corresponding to the global lambda [0..1]
label localParameter(scalar& lambda) const;
@ -94,30 +85,50 @@ public:
// Constructors
//- Construct from components
explicit polyLine
(
const pointField& points, //!< The poly-line points
const bool notImplementedClosed = false
);
//- Construct from begin, intermediate, end points
polyLine
(
const pointField&,
const point& start, //!< The start point
const pointField& intermediate, //!< The intermediate points
const point& end, //!< The end point
const bool notImplementedClosed = false
);
// Static Member Functions
//- Concatenate begin, intermediate and end points
static tmp<pointField> concat
(
const point& start, //!< The start point
const pointField& intermediate, //!< The intermediate points
const point& end //!< The end point
);
// Member Functions
//- Return const-access to the control-points
const pointField& points() const;
//- Return the number of line segments
//- The number of line segments
label nSegments() const;
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
point position(const scalar) const;
//- Return the point position corresponding to the local parameter
//- The point position corresponding to the local parameter
// 0 <= lambda <= 1 on the given segment
point position(const label segment, const scalar) const;
//- Return the length of the curve
//- The length of the curve
scalar length() const;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -48,11 +48,11 @@ Foam::blockEdges::polyLineEdge::polyLineEdge
const pointField& ps,
const label start,
const label end,
const pointField& otherPoints
const pointField& intermediate
)
:
blockEdge(ps, start, end),
polyLine(appendEndPoints(ps, start_, end_, otherPoints))
polyLine(ps[start_], intermediate, ps[end_])
{}
@ -66,7 +66,7 @@ Foam::blockEdges::polyLineEdge::polyLineEdge
)
:
blockEdge(dict, index, ps, is),
polyLine(appendEndPoints(ps, start_, end_, pointField(is)))
polyLine(ps[start_], pointField(is), ps[end_])
{}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -77,19 +77,19 @@ public:
//- Construct from components
polyLineEdge
(
const pointField&,
const label start,
const label end,
const pointField& otherPoints
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end, //!< End point in referenced point field
const pointField& intermediate //!< The intermediate points
);
//- Construct from Istream
//- Construct from Istream and point field.
polyLineEdge
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField&,
const pointField& points, //!< Referenced point field
Istream& is
);
@ -100,11 +100,11 @@ public:
// Member Functions
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
point position(const scalar lambda) const;
//- Return the length of the curve
//- The length of the curve
scalar length() const;
};

View File

@ -59,7 +59,7 @@ Foam::projectCurveEdge::projectCurveEdge
geometry_(geometry)
{
wordList names(is);
surfaces_.setSize(names.size());
surfaces_.resize(names.size());
forAll(names, i)
{
surfaces_[i] = geometry_.findSurfaceID(names[i]);
@ -83,6 +83,14 @@ Foam::projectCurveEdge::projectCurveEdge
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::point
Foam::projectCurveEdge::position(const scalar) const
{
NotImplemented;
return point::max;
}
Foam::tmp<Foam::pointField>
Foam::projectCurveEdge::position(const scalarList& lambdas) const
{
@ -101,8 +109,8 @@ Foam::projectCurveEdge::position(const scalarList& lambdas) const
}
tmp<pointField> tpoints(new pointField(lambdas.size()));
pointField& points = tpoints.ref();
auto tpoints = tmp<pointField>::New(lambdas.size());
auto& points = tpoints.ref();
const point& startPt = points_[start_];
const point& endPt = points_[end_];
@ -149,10 +157,11 @@ Foam::projectCurveEdge::position(const scalarList& lambdas) const
// Upper limit for number of iterations
const label maxIter = 10;
constexpr label maxIter = 10;
// Residual tolerance
const scalar relTol = 0.1;
const scalar absTol = 1e-4;
constexpr scalar relTol = 0.1;
constexpr scalar absTol = 1e-4;
scalar initialResidual = 0.0;
@ -258,4 +267,11 @@ Foam::projectCurveEdge::position(const scalarList& lambdas) const
}
Foam::scalar Foam::projectCurveEdge::length() const
{
NotImplemented;
return 1;
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,6 +46,7 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class pointConstraint;
/*---------------------------------------------------------------------------*\
@ -81,13 +82,13 @@ public:
// Constructors
//- Construct from Istream setting pointsList
//- Construct from Istream and point field.
projectCurveEdge
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField& points,
const pointField& points, //!< Referenced point field
Istream& is
);
@ -98,24 +99,18 @@ public:
// Member Functions
//- Return the point positions corresponding to the curve parameters
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
virtual point position(const scalar) const
{
NotImplemented;
return point::max;
}
// \note NotImplemented
virtual point position(const scalar) const;
//- Return the point positions corresponding to the curve parameters
//- The point positions corresponding to the curve parameters
// 0 <= lambda <= 1
virtual tmp<pointField> position(const scalarList&) const;
//- Return the length of the curve
virtual scalar length() const
{
NotImplemented;
return 1;
}
//- The length of the curve
// \note NotImplemented
virtual scalar length() const;
};

View File

@ -26,13 +26,12 @@ License
\*---------------------------------------------------------------------------*/
#include "searchableSurfacesQueries.H"
#include "projectEdge.H"
#include "unitConversion.H"
#include "addToRunTimeSelectionTable.H"
#include "pointConstraint.H"
#include "searchableSurfacesQueries.H"
#include "OBJstream.H"
#include "linearInterpolationWeights.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -146,8 +145,8 @@ Foam::projectEdge::position(const scalarList& lambdas) const
}
tmp<pointField> tpoints(new pointField(lambdas.size()));
pointField& points = tpoints.ref();
auto tpoints = tmp<pointField>::New(lambdas.size());
auto& points = tpoints.ref();
const point& startPt = points_[start_];
const point& endPt = points_[end_];
@ -161,10 +160,11 @@ Foam::projectEdge::position(const scalarList& lambdas) const
// Upper limit for number of iterations
const label maxIter = 10;
constexpr label maxIter = 10;
// Residual tolerance
const scalar relTol = 0.1;
const scalar absTol = 1e-4;
constexpr scalar relTol = 0.1;
constexpr scalar absTol = 1e-4;
scalar initialResidual = 0.0;
@ -270,4 +270,11 @@ Foam::projectEdge::position(const scalarList& lambdas) const
}
Foam::scalar Foam::projectEdge::length() const
{
NotImplemented;
return 1;
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -46,6 +46,7 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class pointConstraint;
/*---------------------------------------------------------------------------*\
@ -84,13 +85,13 @@ public:
// Constructors
//- Construct from Istream setting pointsList
//- Construct from Istream and point field.
projectEdge
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField& points,
const pointField& points, //!< Referenced point field
Istream& is
);
@ -101,20 +102,17 @@ public:
// Member Functions
//- Return the point positions corresponding to the curve parameters
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
virtual point position(const scalar) const;
//- Return the point positions corresponding to the curve parameters
//- The point positions corresponding to the curve parameters
// 0 <= lambda <= 1
virtual tmp<pointField> position(const scalarList&) const;
//- Return the length of the curve
virtual scalar length() const
{
NotImplemented;
return 1;
}
//- The length of the edge
// \note NotImplemented
virtual scalar length() const;
};

View File

@ -134,7 +134,7 @@ Foam::point Foam::CatmullRomSpline::position
Foam::scalar Foam::CatmullRomSpline::length() const
{
NotImplemented;
return 1.0;
return 1;
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -79,21 +80,12 @@ class CatmullRomSpline
:
public polyLine
{
// Private Member Functions
//- No copy construct
CatmullRomSpline(const CatmullRomSpline&) = delete;
//- No copy assignment
void operator=(const CatmullRomSpline&) = delete;
public:
// Constructors
//- Construct from components
CatmullRomSpline
explicit CatmullRomSpline
(
const pointField& knots,
const bool notImplementedClosed = false
@ -102,15 +94,16 @@ public:
// Member Functions
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
point position(const scalar lambda) const;
//- Return the point position corresponding to the local parameter
//- The point position corresponding to the local parameter
// 0 <= lambda <= 1 on the given segment
point position(const label segment, const scalar lambda) const;
//- Return the length of the curve
//- The length of the curve
// \note NotImplemented
scalar length() const;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,9 +27,9 @@ License
\*---------------------------------------------------------------------------*/
#include "splineEdge.H"
#include "polyLine.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
@ -59,7 +59,10 @@ Foam::blockEdges::splineEdge::splineEdge
)
:
blockEdge(points, start, end),
CatmullRomSpline(appendEndPoints(points, start, end, internalPoints))
CatmullRomSpline
(
polyLine::concat(points[start_], internalPoints, points[end_])
)
{}
@ -73,13 +76,16 @@ Foam::blockEdges::splineEdge::splineEdge
)
:
blockEdge(dict, index, points, is),
CatmullRomSpline(appendEndPoints(points, start_, end_, pointField(is)))
CatmullRomSpline
(
polyLine::concat(points[start_], pointField(is), points[end_])
)
{
token t(is);
is.putBack(t);
token tok(is);
is.putBack(tok);
// discard unused start/end tangents
if (t == token::BEGIN_LIST)
// Discard unused start/end tangents
if (tok == token::BEGIN_LIST)
{
vector tangent0Ignored(is);
vector tangent1Ignored(is);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,6 +30,10 @@ Class
Description
A blockEdge interface for Catmull-Rom splines.
See also
BSpline
CatmullRomSpline
SourceFiles
splineEdge.C
@ -77,19 +81,19 @@ public:
//- Construct from components
splineEdge
(
const pointField&,
const label start,
const label end,
const pointField& points, //!< Referenced point field
const label start, //!< Start point in referenced point field
const label end, //!< End point in referenced point field
const pointField& internalPoints
);
//- Construct from Istream, setting pointsList
//- Construct from Istream and point field.
splineEdge
(
const dictionary& dict,
const label index,
const searchableSurfaces& geometry,
const pointField&,
const pointField& points, //!< Referenced point field
Istream&
);
@ -100,11 +104,12 @@ public:
// Member Functions
//- Return the point position corresponding to the curve parameter
//- The point position corresponding to the curve parameter
// 0 <= lambda <= 1
virtual point position(const scalar) const;
//- Return the length of the spline curve (not implemented)
//- The length of the spline curve
// \note NotImplemented
virtual scalar length() const;
};