polyline.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) 2020 Ivor Clifford/Paul Scherrer Institut
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "polyline.H"
30#include "interpolateXY.H"
31#include "quaternion.H"
32
33// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34
35namespace Foam
36{
37namespace extrudeModels
38{
39
40// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41
43
45
46
47// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
48
50:
51 extrudeModel(typeName, dict),
52 geometry_(0),
53 vertices_(coeffDict_.lookup("vertices")),
54 segments_
55 (
56 coeffDict_.lookup("edges"),
57 blockEdge::iNew(coeffDict_, geometry_, vertices_)
58 ),
59 x_(segments_.size() + 1),
60 y_(segments_.size() + 1),
61 relTol_(coeffDict_.getOrDefault<scalar>("toleranceCheck", SMALL))
62{
63 // Check continuity and smoothness of the supplied polyline
64 for (label i=1; i < segments_.size(); ++i)
65 {
66 // Check continuity
67 const vector x0 = segments_[i-1].position(1);
68 const vector x1 = segments_[i].position(0);
69
70 if (mag(x1-x0) > SMALL)
71 {
73 << "Supplied polyline is not continuous." << endl
75 }
76
77 // Check smoothness
78 const vector v0 =
80 (
81 segments_[i-1].position(1)
82 - segments_[i-1].position(1-DELTA)
83 );
84
85 const vector v1 =
87 (
88 segments_[i].position(DELTA)
89 - segments_[i].position(0)
90 );
91
92 if ((v1 & v0) < (1 - relTol_))
93 {
95 << "Supplied polyline is not smooth." << endl
97 }
98 }
99
100 // Calculate cumulative length along polyline
101 x_[0] = 0;
102 y_[0] = 0;
103 scalar totalLength = 0;
104 forAll(segments_, i)
105 {
106 totalLength += segments_[i].length();
107 x_[i+1] = totalLength;
108 y_[i+1] = i+1;
109 }
110
111 // Normalise cumulative length (0 <= x <= 1)
112 x_ /= totalLength;
113
114 // Position vector and direction at start of polyline
115 positionAndDirection(0, p0_, n0_);
116
117 if (debug)
118 {
119 Info
120 << tab << "Polyline start: " << p0_ << nl
121 << tab << "Polyline normal at start: " << n0_ << nl
122 << tab << "Polyline end: "
123 << segments_.last().position(1) << nl
124 << tab << "Total length: " << totalLength << endl;
125 }
126}
127
128
129// * * * * * * * * * * * * * * * * Operators * * * * * * * * * * * * * * * * //
130
132(
133 const point& surfacePoint,
134 const vector& surfaceNormal,
135 const label layer
136) const
137{
138 // Offset between supplied point and origin of polyline
139 vector dp = (surfacePoint - p0_);
140
141 // If this is the first layer, check whether the start of the
142 // polyline seems to lie on the surface
143 if (layer == 0)
144 {
145 if (mag((dp/mag(dp)) & n0_) > relTol_)
146 {
148 << "The starting point of the polyline does not appear "
149 << "to lie of the supplied surface. Apparent absolute "
150 << "misalignment is " << (dp & n0_) << endl;
151 }
152 }
153
154 // Position and direction vector at end of layer
155 vector p;
156 vector n;
157 positionAndDirection(sumThickness(layer), p, n);
158
159 // Angle between normal vector and normal at origin
160 scalar cosTheta = (n & n0_);
161
162 // Rotate point to align with current normal vector
163 if (cosTheta < (1-SMALL))
164 {
165 const vector axis = normalised(n0_ ^ n);
166
167 dp = quaternion(axis, cosTheta, true).transform(dp);
168 }
169
170 return p + dp;
171}
172
173
175(
176 const scalar lambda,
177 vector& p,
178 vector& n
179) const
180{
181 // Find associated segment and position for supplied lambda
182 scalar y = interpolateXY(lambda, x_, y_);
183 int i = floor(y);
184 scalar s = y - i;
185 if (i > segments_.size()-1)
186 {
187 i = segments_.size()-1;
188 s = 1.0;
189 }
190
191 // Position vector
192 p = segments_[i].position(s);
193
194 // Normal vector at current position
195 // Estimated normal vector using numerical differencing since
196 // blockEdge doesn't include a normal function
197
198 n = normalised
199 (
200 segments_[i].position(min(s + DELTA, 1))
201 - segments_[i].position(max(s - DELTA, 0))
202 );
203}
204
205
206// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
207
208} // End namespace extrudeModels
209} // End namespace Foam
210
211// ************************************************************************* //
scalar y
label n
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
T & last()
Return reference to the last element of the list.
Definition: UPtrListI.H:176
Define a curved edge that is parameterized for 0<lambda<1 between the start/end points.
Definition: blockEdge.H:64
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Top level extrusion model class.
Definition: extrudeModel.H:77
Extrudes by transforming points along a polyline provided as a series of points and edge segments....
Definition: polyline.H:83
void positionAndDirection(const scalar lambda, vector &p, vector &n) const
Definition: polyline.C:175
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
Quaternion class used to perform rotations in 3D space.
Definition: quaternion.H:58
vector transform(const vector &v) const
Rotate the given vector.
Definition: quaternionI.H:331
Lookup type of boundary radiation properties.
Definition: lookup.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
volScalarField & p
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Interpolates y values from one curve to another with a different x distribution.
#define WarningInFunction
Report a warning using Foam::Warning.
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:47
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
Definition: quaternionI.H:680
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< Type > interpolateXY(const scalarField &xNew, const scalarField &xOld, const Field< Type > &yOld)
Definition: interpolateXY.C:41
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
constexpr char tab
The tab '\t' character(0x09)
Definition: Ostream.H:52
dictionary dict
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333