Loading...
Searching...
No Matches
arcEdge.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2020-2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "arcEdge.H"
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
36{
37namespace blockEdges
38{
41}
42}
43
44
45// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
46
47void Foam::blockEdges::arcEdge::calcFromMidPoint
48(
49 const point& p1,
50 const point& p3,
51 const point& p2
52)
53{
54 const vector a = p2 - p1;
55 const vector b = p3 - p1;
56
57 // Find centre of arcEdge
58 const scalar asqr = a & a;
59 const scalar bsqr = b & b;
60 const scalar adotb = a & b;
61
62 const scalar denom = asqr*bsqr - adotb*adotb;
63
64 if (mag(denom) < ROOTVSMALL)
65 {
67 << denom
68 << abort(FatalError);
69 }
70
71 const scalar fact = 0.5*(bsqr - adotb)/denom;
72
73 const point centre = p1 + 0.5*a + fact*((a ^ b) ^ a);
74
75 // Position vectors from centre
76 const vector r1(p1 - centre);
77 const vector r2(p2 - centre);
78 const vector r3(p3 - centre);
79
80 const scalar mag1(mag(r1));
81 const scalar mag3(mag(r3));
82
83 vector arcAxis(r1 ^ r3);
84
85 // The radius from r1 and from r3 will be identical
86 radius_ = mag(r3);
87
88
89 // Determine the angle
90 angle_ = acos((r1 & r3)/(mag1*mag3));
91
92 // Check if the vectors define an exterior or an interior arcEdge
93 if (((r1 ^ r2) & (r1 ^ r3)) < 0.0)
94 {
95 angle_ = constant::mathematical::twoPi - angle_;
96 }
97
98 if (angle_ <= constant::mathematical::pi)
99 {
100 if (mag(arcAxis)/(mag1*mag3) < 0.001)
101 {
102 arcAxis = r1 ^ r2;
103 }
104 }
105 else
106 {
107 arcAxis = -arcAxis;
108 }
109
110 // Corresponding local cylindrical coordinate system
111 cs_ = coordSystem::cylindrical(centre, arcAxis, r1);
112}
113
114
115void Foam::blockEdges::arcEdge::calcFromCentre
116(
117 const point& p1,
118 const point& p3,
119 const point& centre,
120 bool adjustCentre,
121 scalar rMultiplier
122)
123{
124 // Position vectors from centre
125 const vector r1(p1 - centre);
126 const vector r3(p3 - centre);
127
128 const scalar mag1(mag(r1));
129 const scalar mag3(mag(r3));
130
131 const vector chord(p3 - p1);
132
133 const vector arcAxis(r1 ^ r3);
134
135 // The average radius
136 radius_ = 0.5*(mag1 + mag3);
137
138 // The included angle
139 angle_ = acos((r1 & r3)/(mag1*mag3));
140
141 // TODO? check for 180 degrees (co-linear points)?
142
143 bool needsAdjust = false;
144
145 if (adjustCentre)
146 {
147 needsAdjust = !equal(mag1, mag3);
148
149 if (!equal(rMultiplier, 1))
150 {
151 // The min radius is constrained by the chord,
152 // otherwise bad things will happen.
153
154 needsAdjust = true;
155 radius_ *= rMultiplier;
156 radius_ = max(radius_, (1.001*0.5*mag(chord)));
157 }
158 }
159
160 if (needsAdjust)
161 {
162 // The centre is not equidistant to p1 and p3.
163 // Use the chord and the arcAxis to determine the vector to
164 // the midpoint of the chord and adjust the centre along this
165 // line.
166
167 const point newCentre =
168 (
169 (0.5 * (p3 + p1)) // mid-chord point
170 + sqrt(sqr(radius_) - 0.25 * magSqr(chord))
171 * normalised(arcAxis ^ chord) // mid-chord -> centre
172 );
173
178
179 // Recalculate - do attempt to readjust
180 calcFromCentre(p1, p3, newCentre, false);
181 }
182 else
183 {
184 // Corresponding local cylindrical coordinate system
185 cs_ = coordSystem::cylindrical(centre, arcAxis, r1);
186 }
187}
188
189
190// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
191
192Foam::blockEdges::arcEdge::arcEdge
193(
194 const pointField& points,
195 const point& origin,
196 const edge& fromTo
197)
198:
199 blockEdge(points, fromTo),
200 radius_(0),
201 angle_(0),
202 cs_()
203{
204 calcFromCentre(firstPoint(), lastPoint(), origin);
205}
206
207
208Foam::blockEdges::arcEdge::arcEdge
209(
210 const pointField& points,
211 const edge& fromTo,
212 const point& midPoint
213)
214:
215 blockEdge(points, fromTo),
216 radius_(0),
217 angle_(0),
218 cs_()
219{
220 calcFromMidPoint(firstPoint(), lastPoint(), midPoint);
221}
222
223
224Foam::blockEdges::arcEdge::arcEdge
225(
226 const pointField& points,
227 const point& origin,
228 const label from,
229 const label to
230)
231:
232 arcEdge(points, origin, edge(from,to))
233{}
234
235
236Foam::blockEdges::arcEdge::arcEdge
237(
238 const pointField& points,
239 const label from,
240 const label to,
242)
243:
244 arcEdge(points, edge(from,to), midPoint)
245{}
246
247
248Foam::blockEdges::arcEdge::arcEdge
249(
250 const dictionary& dict,
251 const label index,
252 const searchableSurfaces&,
253 const pointField& points,
254 Istream& is
255)
256:
257 blockEdge(dict, index, points, is),
258 radius_(0),
259 angle_(0),
260 cs_()
261{
262 point p;
263
264 token tok(is);
265 if (tok.isWord())
266 {
267 // Can be
268 // - origin (0 0 0)
269 // - origin 1.2 (0 0 0)
270
271 scalar rMultiplier = 1;
272
273 is >> tok;
274 if (tok.isNumber())
275 {
276 rMultiplier = tok.number();
277 }
278 else
279 {
280 is.putBack(tok);
281 }
282
283 is >> p; // The origin (centre)
284
285 calcFromCentre(firstPoint(), lastPoint(), p, true, rMultiplier);
286 }
287 else
288 {
289 is.putBack(tok);
290
291 is >> p; // A mid-point
292
293 calcFromMidPoint(firstPoint(), lastPoint(), p);
294 }
295
296 if (debug)
297 {
298 Info<< "arc " << start_ << ' ' << end_ << ' '
299 << position(0.5) << " origin " << cs_.origin() << " // ";
300 cs_.rotation().write(Info);
302 }
303}
304
305
306// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
307
309{
310 #ifdef FULLDEBUG
311 if (lambda < -SMALL || lambda > 1 + SMALL)
312 {
314 << "Limit parameter to [0-1] range: " << lambda << nl;
315 }
316 #endif
317
318 if (lambda < SMALL)
319 {
320 return firstPoint();
321 }
322 else if (lambda >= 1 - SMALL)
323 {
324 return lastPoint();
325 }
326
327 return cs_.globalPosition(vector(radius_, (lambda*angle_), 0));
328}
329
330
332{
333 return (radius_*angle_);
334}
335
336
337// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
void putBack(const token &tok)
Put back a token (copy). Only a single put back is permitted.
Definition Istream.C:71
Define a curved edge that is parameterized for 0<lambda<1 between the start/end points.
Definition blockEdge.H:61
blockEdge(const pointField &points, const label from, const label to)
Construct from components.
Definition blockEdge.H:106
const point & lastPoint() const
The location of the last point.
Definition blockEdgeI.H:48
const label end_
Index of the last point.
Definition blockEdge.H:79
const label start_
Index of the first point.
Definition blockEdge.H:74
const point & firstPoint() const
The location of the first point.
Definition blockEdgeI.H:42
A blockEdge defined as an arc of a circle.
Definition arcEdge.H:78
point position(const scalar lambda) const
The point corresponding to the curve parameter [0-1].
Definition arcEdge.C:301
scalar length() const noexcept
The length of the curve.
Definition arcEdge.C:324
A cylindrical coordinate system (r-theta-z). The coordinate system angle theta is always in radians.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Definition edge.H:62
Mid-point interpolation (weighting factors = 0.5) scheme class.
Definition midPoint.H:54
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
A token holds an item read from Istream.
Definition token.H:70
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE).
Definition tokenI.H:1004
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
volScalarField & p
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
const pointField & points
#define InfoInFunction
Report an information message using Foam::Info.
A namespace for various blockEdge types.
Definition arcEdge.C:31
constexpr scalar pi(M_PI)
constexpr scalar twoPi(2 *M_PI)
Namespace for handling debugging switches.
Definition debug.C:45
Namespace for OpenFOAM.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
dimensionedSymmTensor sqr(const dimensionedVector &dv)
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
bool equal(const T &a, const T &b)
Compare two values for equality.
Definition label.H:180
messageStream Info
Information stream (stdout output on master, null elsewhere).
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
errorManip< error > abort(error &err)
Definition errorManip.H:139
vector point
Point is a vector.
Definition point.H:37
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
dimensionedScalar acos(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
volScalarField & b
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
Unit conversion functions.