KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
curve_tessellation.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Andreas Apostolatos
11 // Tobias Teschemacher
12 // Thomas Oberbichler
13 //
14 //
15 // Ported from the ANurbs library (https://github.com/oberbichler/ANurbs)
16 //
17 
18 #if !defined(KRATOS_CURVE_TESSELLATION_H_INCLUDED )
19 #define KRATOS_CURVE_TESSELLATION_H_INCLUDED
20 
21 #include "utilities/math_utils.h"
22 #include "geometries/geometry.h"
24 
26 #include "containers/array_1d.h"
27 
28 namespace Kratos {
29 
30 template <class TContainerPointType>
32 {
33 public:
34 
37 
40  typedef std::vector<std::pair<double, CoordinatesArrayType>> TessellationType;
42  typedef typename GeometryType::SizeType SizeType;
43 
47 
50  {
51  }
52 
56 
57  /* INTERFACE FOR NURBS GEOMETRIES
58  * @brief This method tessellates a curve and stores the tessellation in the class.
59  *
60  * @param rGeometry Reference to the geometry
61  * @param PolynomialDegree The polynomial degree of the curve
62  * @param DomainInterval The curve interval which is to be tessellated
63  * @param rKnotSpanIntervals knot span intervals laying in the DomainInterval
64  * @param Tolerance for the chordal error
65  *
66  * @see ComputeTessellation
67  */
68  void Tessellate(
69  const GeometryType& rGeometry,
70  const int PolynomialDegree,
71  const NurbsInterval DomainInterval,
72  const std::vector<NurbsInterval>& rKnotSpanIntervals,
73  const double Tolerance)
74  {
75  mTesselation = ComputeTessellation(
76  rGeometry,
77  PolynomialDegree,
78  DomainInterval,
79  rKnotSpanIntervals,
80  Tolerance);
81  }
82 
83  /* INTERFACE FOR ALL GEOMETRIES
84  * @brief This method tessellates a curve and stores the tessellation in the class.
85  *
86  * @param rGeometry Reference to the geometry
87  * @param Tolerance Tolerance for the chordal error
88  * @param NumberOfGuessesPerInterval triggers the convergence with introducing more points per iteration.
89  * @param ToSurfaceParameter defines if the tesselation is computed in
90  * global coordinates or in local coordinates of the underlying surface.
91  *
92  * @see ComputeTessellation
93  */
94  void Tessellate(
95  const GeometryType& rGeometry,
96  const double Tolerance,
97  const int NumberOfGuessesPerInterval = 1,
98  bool ToSurfaceParameter = false)
99  {
100  std::vector<double> span_intervals;
101  rGeometry.SpansLocalSpace(span_intervals, 0);
102 
103  Tessellate(
104  rGeometry,
105  span_intervals,
106  NumberOfGuessesPerInterval,
107  Tolerance,
108  ToSurfaceParameter);
109  }
110 
111  /* INTERFACE FOR ALL GEOMETRIES
112  * @brief This method tessellates a possibly trimmed curve using geometry
113  * provided interfaces and stores the tessellation in the class.
114  *
115  * @param rGeometry Reference to the geometry
116  * @param rSpanIntervals The curve intervals which are being tessellated
117  * @param rKnotSpanIntervals Reference to the knot span intervals laying in the DomainInterval
118  * @param Tolerance Tolerance for the chordal error
119  * @param ToSurfaceParameter defines if the tesselation is computed in
120  * global coordinates or in local coordinates of the underlying surface.
121  *
122  * @see ComputeTessellation
123  */
125  const GeometryType& rGeometry,
126  const std::vector<double>& rSpanIntervals,
127  const double Tolerance,
128  const int NumberOfGuessesPerInterval = 1,
129  bool ToSurfaceParameter = false)
130  {
131  NurbsInterval this_interval(rSpanIntervals[0], rSpanIntervals[rSpanIntervals.size() - 1]);
132 
133  std::vector<NurbsInterval> KnotSpanIntervals(rSpanIntervals.size() - 1);
134 
135  for (IndexType i = 0; i < rSpanIntervals.size() - 1; ++i) {
136  KnotSpanIntervals[i] = NurbsInterval(rSpanIntervals[i], rSpanIntervals[i + 1]);
137  }
138 
139  mTesselation = ComputeTessellation(
140  rGeometry,
141  NumberOfGuessesPerInterval,
142  this_interval,
143  KnotSpanIntervals,
144  Tolerance,
145  ToSurfaceParameter);
146  }
147 
148  /* INTERFACE FOR NURBS GEOMETRIES
149  * @brief This method returns the tessellation of a curve
150  *
151  * @param pGeometry Pointer to the geometry
152  * @param PolynomialDegree The polynomial degree of the curve
153  * @param DomainInterval The curve interval which is to be tessellated
154  * @param KnotSpanIntervals The knot span intervals laying in the DomainInterval
155  * @param Tolerance Tolerance for the chordal error
156  * @param ToSurfaceParameter defines if the tesselation is computed in
157  * global coordinates or in local coordinates of the underlying surface.
158  *
159  * @return std::vector<std::pair<double, Vector>> tessellation
160  * @see ANurbs library (https://github.com/oberbichler/ANurbs)
161  */
163  const GeometryType& rGeometry,
164  const int PolynomialDegree,
165  const NurbsInterval DomainInterval,
166  const std::vector<NurbsInterval>& rKnotSpanIntervals,
167  const double Tolerance,
168  bool ToSurfaceParameter = false
169  )
170  {
171  TessellationType sample_points;
172  TessellationType points;
173 
174  typename GeometryType::CoordinatesArrayType point;
175 
176  // compute sample points
177  for (const auto& span : rKnotSpanIntervals) {
178  const NurbsInterval normalized_span = DomainInterval.GetNormalizedInterval(span);
179 
180  if (normalized_span.GetLength() < 1e-7) {
181  continue;
182  }
183 
184  const double t = normalized_span.GetT0();
186  t0[0] = span.GetT0();
187 
189  point, t0, rGeometry, ToSurfaceParameter);
190 
191  sample_points.emplace_back(t, point);
192  }
193 
194  typename GeometryType::CoordinatesArrayType t_at_normalized;
195  t_at_normalized[0] = DomainInterval.GetParameterAtNormalized(1.0);
196 
198  point, t_at_normalized, rGeometry, ToSurfaceParameter);
199 
200  sample_points.emplace_back(1.0, point);
201 
202  std::sort(std::begin(sample_points), std::end(sample_points),
203  [](std::pair<double, Vector> const& lhs, std::pair<double, Vector> const& rhs) {
204  return std::get<0>(lhs) > std::get<0>(rhs);
205  }
206  );
207 
208  // compute polyline
209 
210  const int n = PolynomialDegree * 2 + 1;
211 
212  while (true) {
213  const auto parameter_point_a = sample_points.back();
214 
215  const auto t_a = std::get<0>(parameter_point_a);
216  const auto point_a = std::get<1>(parameter_point_a);
217 
218  sample_points.pop_back();
219 
220  points.emplace_back(DomainInterval.GetParameterAtNormalized(t_a), point_a);
221 
222  if (sample_points.size() == 0) {
223  break;
224  }
225 
226  while (true) {
227  const auto parameter_point_b = sample_points.back();
228 
229  const auto t_b = std::get<0>(parameter_point_b);
230  const auto point_b = std::get<1>(parameter_point_b);
231 
232  double max_distance{ 0 };
233  std::pair<double, Vector> max_point;
234 
235  for (int i = 1; i <= n; i++) {
236  const double t = NurbsInterval::GetParameterAtNormalized(t_a,
237  t_b, i / (double(n) + 1.0));
238 
239  t_at_normalized[0] = DomainInterval.GetParameterAtNormalized(t);
240 
242  point, t_at_normalized, rGeometry, ToSurfaceParameter);
243 
244  const double distance = DistanceToLine(point, point_a,
245  point_b);
246 
247  if (distance > max_distance) {
248  max_distance = distance;
249  max_point = { t, point };
250  }
251  }
252 
253  if (max_distance < Tolerance) {
254  break;
255  }
256 
257  sample_points.push_back(max_point);
258  }
259  }
260 
261  return points;
262  }
263 
265  CoordinatesArrayType& rGlobalCoordinates,
266  const CoordinatesArrayType& crLocaCoordinates,
267  const GeometryType& rGeometry,
268  bool to_surface_parameter = false
269  )
270  {
271  if (!to_surface_parameter) {
272  rGeometry.GlobalCoordinates(
273  rGlobalCoordinates, crLocaCoordinates);
274  return;
275  }
276  rGlobalCoordinates = crLocaCoordinates;
277  rGeometry.Calculate(PARAMETER_2D_COORDINATES, rGlobalCoordinates);
278  }
279 
280  /* @brief This method returns polygon of this curve with equal curve segments.
281  * @param pGeometry Pointer to the geometry
282  * @param NumberOfPoints The total amount of nodes including start and end node.
283  * @param Start parameter of polygon.
284  * @param End parameter of polygon.
285  */
287  const GeometryType& rGeometry,
288  const SizeType NumberOfPoints,
289  const double Start,
290  const double End)
291  {
292  TessellationType points(NumberOfPoints);
293 
294  CoordinatesArrayType parameter = ZeroVector(3);
295 
296  double length = End - Start;
297  double delta_length = length / (NumberOfPoints - 1);
298 
299  // compute sample points
300  for (IndexType i = 0; i < NumberOfPoints; ++i) {
301  parameter[0] = Start + delta_length * i;
302  CoordinatesArrayType result;
303  rGeometry.GlobalCoordinates(result, parameter);
304  points[i] = { parameter[0], result };
305  }
306 
307  return points;
308  }
309 
310  /* @brief This method iterates through all points within the provided
311  * polygon and returns the closest point.
312  *
313  * @param CoordinatesArrayType external point
314  * @param rClosestPointGlobalCoordinates closest point within polygon in global coordinates.
315  * @param rClosestPointLocalCoordinates closest point within polygon in local coordinates.
316  * @param rTesselation corresponding tessellation.
317  */
318  static void GetClosestPoint(
319  const CoordinatesArrayType& rPointGlobalCoordinates,
320  CoordinatesArrayType& rClosestPointGlobalCoordinates,
321  CoordinatesArrayType& rClosestPointLocalCoordinates,
322  const TessellationType& rTesselation)
323  {
324  double distance = std::numeric_limits<double>::max();
325  double new_distance;
326  for (IndexType i = 0; i < rTesselation.size(); ++i)
327  {
328  new_distance = norm_2(rPointGlobalCoordinates - std::get<1>(rTesselation[i]));
329  if (new_distance < distance)
330  {
331  distance = new_distance;
332  rClosestPointGlobalCoordinates = std::get<1>(rTesselation[i]);
333  rClosestPointLocalCoordinates[0] = std::get<0>(rTesselation[i]);
334  }
335  }
336  }
337 
338  /* @brief This method iterates through all points within the
339  * polygon and returns the closest point.
340  *
341  * @param CoordinatesArrayType external point
342  * @param rClosestPointGlobalCoordinates closest point within polygon in global coordinates.
343  * @param rClosestPointLocalCoordinates closest point within polygon in local coordinates.
344  * @param rTesselation corresponding tessellation.
345  */
347  const CoordinatesArrayType& rPointGlobalCoordinates,
348  CoordinatesArrayType& rClosestPointGlobalCoordinates,
349  CoordinatesArrayType& rClosestPointLocalCoordinates) const
350  {
352  rPointGlobalCoordinates,
353  rClosestPointGlobalCoordinates,
354  rClosestPointLocalCoordinates,
355  mTesselation);
356  }
357 
358  /* @brief This method returns the already computed tessellation of a curve
359  * @return return std::vector<std::pair<double, Vector>> tessellation
360  */
362  return mTesselation;
363  }
364 
365 private:
368 
369  TessellationType mTesselation;
370 
374 
375  static double DistanceToLine(
376  const CoordinatesArrayType& rPoint,
377  const CoordinatesArrayType& rLineA,
378  const CoordinatesArrayType& rLineB
379  )
380  {
381  CoordinatesArrayType vector_v = rLineA - rPoint;
382  CoordinatesArrayType vector_u = rLineB - rLineA;
383 
385  }
386 
388 };
389 
390 } // namespace CurveTessellation
391 
392 #endif // KRATOS_CURVE_TESSELLATION_H_INCLUDED defined
Definition: curve_tessellation.h:32
Geometry< typename TContainerPointType::value_type > GeometryType
Definition: curve_tessellation.h:38
std::vector< std::pair< double, CoordinatesArrayType > > TessellationType
Definition: curve_tessellation.h:40
static TessellationType ComputeTessellation(const GeometryType &rGeometry, const int PolynomialDegree, const NurbsInterval DomainInterval, const std::vector< NurbsInterval > &rKnotSpanIntervals, const double Tolerance, bool ToSurfaceParameter=false)
Definition: curve_tessellation.h:162
void Tessellate(const GeometryType &rGeometry, const std::vector< double > &rSpanIntervals, const double Tolerance, const int NumberOfGuessesPerInterval=1, bool ToSurfaceParameter=false)
Definition: curve_tessellation.h:124
GeometryType::CoordinatesArrayType CoordinatesArrayType
Definition: curve_tessellation.h:39
GeometryType::SizeType SizeType
Definition: curve_tessellation.h:42
CurveTessellation()
Conctructor for tessellation of a nurbs curve.
Definition: curve_tessellation.h:49
void Tessellate(const GeometryType &rGeometry, const double Tolerance, const int NumberOfGuessesPerInterval=1, bool ToSurfaceParameter=false)
Definition: curve_tessellation.h:94
void Tessellate(const GeometryType &rGeometry, const int PolynomialDegree, const NurbsInterval DomainInterval, const std::vector< NurbsInterval > &rKnotSpanIntervals, const double Tolerance)
Definition: curve_tessellation.h:68
static void GetClosestPoint(const CoordinatesArrayType &rPointGlobalCoordinates, CoordinatesArrayType &rClosestPointGlobalCoordinates, CoordinatesArrayType &rClosestPointLocalCoordinates, const TessellationType &rTesselation)
Definition: curve_tessellation.h:318
static void ComputeGlobalCoordinates(CoordinatesArrayType &rGlobalCoordinates, const CoordinatesArrayType &crLocaCoordinates, const GeometryType &rGeometry, bool to_surface_parameter=false)
Definition: curve_tessellation.h:264
TessellationType GetTessellation()
Definition: curve_tessellation.h:361
static TessellationType ComputePolygon(const GeometryType &rGeometry, const SizeType NumberOfPoints, const double Start, const double End)
Definition: curve_tessellation.h:286
void GetClosestPoint(const CoordinatesArrayType &rPointGlobalCoordinates, CoordinatesArrayType &rClosestPointGlobalCoordinates, CoordinatesArrayType &rClosestPointLocalCoordinates) const
Definition: curve_tessellation.h:346
GeometryType::IndexType IndexType
Definition: curve_tessellation.h:41
Geometry base class.
Definition: geometry.h:71
virtual CoordinatesArrayType & GlobalCoordinates(CoordinatesArrayType &rResult, CoordinatesArrayType const &LocalCoordinates) const
Definition: geometry.h:2377
virtual void Calculate(const Variable< bool > &rVariable, bool &rOutput) const
Calculate with bool.
Definition: geometry.h:693
std::size_t SizeType
Definition: geometry.h:144
std::size_t IndexType
Definition: geometry.h:137
virtual void SpansLocalSpace(std::vector< double > &rSpans, IndexType LocalDirectionIndex=0) const
Definition: geometry.h:1972
Various mathematical utilitiy functions.
Definition: math_utils.h:62
static double Norm(const Vector &a)
Calculates the norm of vector "a".
Definition: math_utils.h:703
Class for optimized use of intervals.
Definition: nurbs_interval.h:36
double GetLength() const
Definition: nurbs_interval.h:95
NurbsInterval GetNormalizedInterval(const double T0, const double T1) const
Definition: nurbs_interval.h:120
double GetT0() const
Definition: nurbs_interval.h:60
double GetParameterAtNormalized(const double Parameter) const
Definition: nurbs_interval.h:109
Short class definition.
Definition: array_1d.h:61
end
Definition: DEM_benchmarks.py:180
static double max(double a, double b)
Definition: GeometryFunctions.h:79
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
float span
Definition: angle_finder.py:9
rhs
Definition: generate_frictional_mortar_condition.py:297
lhs
Definition: generate_frictional_mortar_condition.py:297
string t0
Definition: kernel_approximation_error.py:61
int t
Definition: ode_solve.py:392
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31