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_axis_intersection.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 
11 
12 #if !defined(KRATOS_CURVE_AXIS_INTERSECTION_INCLUDED )
13 #define KRATOS_CURVE_AXIS_INTERSECTION_INCLUDED
14 
15 
16 // System includes
17 #include <limits>
18 
19 // External includes
20 
21 // Project includes
23 
24 namespace Kratos
25 {
26  template<class TNodeType>
28  {
29  public:
30  typedef std::size_t SizeType;
31  typedef std::size_t IndexType;
32 
34  typedef typename GeometryType::Pointer GeometryPointerType;
36 
38 
39  private:
40  static double BisectionToAxis(
41  const GeometryType& rCurve,
42  double IntersectionAxis,
43  double Parameter1,
44  double Parameter2,
45  IndexType AxisDirectionIndex,
46  double Tolerance = 1e-6)
47  {
48  double parameter_smaller, parameter_bigger;
49  CoordinatesArrayType point_1, point_2;
50  CoordinatesArrayType parameter_1 = ZeroVector(3);
51  parameter_1[0] = Parameter1;
52  CoordinatesArrayType parameter_2 = ZeroVector(3);
53  parameter_2[0] = Parameter2;
54  rCurve.GlobalCoordinates(point_1, parameter_1);
55  rCurve.GlobalCoordinates(point_2, parameter_2);
56 
57  double distance = point_1[AxisDirectionIndex] - IntersectionAxis;
58  if (distance < 0) {
59  parameter_smaller = parameter_1[0];
60  parameter_bigger = parameter_2[0];
61  }
62  else {
63  parameter_smaller = parameter_2[0];
64  parameter_bigger = parameter_1[0];
65  }
66 
67  for (IndexType i = 0; i <= IndexType(50); ++i)
68  {
69  CoordinatesArrayType new_parameter = ZeroVector(3);
70  new_parameter[0] = (parameter_smaller + parameter_bigger) / 2;
71  CoordinatesArrayType point_new;
72  rCurve.GlobalCoordinates(point_new, new_parameter);
73  distance = point_new[AxisDirectionIndex] - IntersectionAxis;
74 
75  if (std::abs(distance) < Tolerance) {
76  return new_parameter[0];
77  }
78  if (distance < 0)
79  parameter_smaller = new_parameter[0];
80  else
81  parameter_bigger = new_parameter[0];
82  }
83 
84  return 0.0;
85  }
86 
87  static void GetSpanIndex(
88  const std::vector<double>& rAxis,
89  IndexType& rSpanIndex,
90  double& rMin,
91  double& rMax,
92  double Parameter,
93  bool Ascending = true)
94  {
95  if (Ascending) {
96  for (IndexType i = 0; i < rAxis.size() - 1; ++i) {
97  KRATOS_DEBUG_ERROR_IF(i == rAxis.size() - 1)
98  << "Point of polygon not within the axis boundaries. Axis are: "
99  << rAxis << ". Searched parameter is: " << Parameter << std::endl;
100 
101  rMin = std::min(rAxis[i], rAxis[i + 1]);
102  rMax = std::max(rAxis[i], rAxis[i + 1]);
103 
104  if ((Parameter >= rMin) && (Parameter < rMax)) {
105  rSpanIndex = i;
106  return;
107  }
108  }
109  }
110  else {
111  for (IndexType i = 0; i < rAxis.size() - 1; ++i) {
112  KRATOS_DEBUG_ERROR_IF(i == rAxis.size() - 1)
113  << "Point of polygon not within the axis boundaries. Axis are: "
114  << rAxis << ". Searched parameter is: " << Parameter << std::endl;
115 
116  rMin = std::max(rAxis[i], rAxis[i + 1]);
117  rMax = std::min(rAxis[i], rAxis[i + 1]);
118 
119  if ((Parameter >= rMin) && (Parameter < rMax)) {
120  rSpanIndex = i;
121  return;
122  }
123  }
124  }
125  }
126 
127  /* @brief sort a std::vector<double> and delete duplicated entries.
128  * @param resulting list to be sorted.
129  * @param Tolerance between duplicated entries.
130  */
131  static void SortUnique(
132  std::vector<double>& rIntersectionParameters,
133  const double Tolerance)
134  {
135  std::sort(std::begin(rIntersectionParameters), std::end(rIntersectionParameters));
136 
137  auto last = std::unique(std::begin(rIntersectionParameters), std::end(rIntersectionParameters),
138  [=](double a, double b) { return b - a < Tolerance; });
139 
140  auto nb_unique = std::distance(std::begin(rIntersectionParameters), last);
141 
142  rIntersectionParameters.resize(nb_unique);
143  }
144 
145  public:
147  std::vector<double>& rIntersectionParameters,
148  const GeometryType& rGeometry,
149  double Start,
150  double End,
151  const std::vector<double>& rAxis1,
152  const std::vector<double>& rAxis2,
153  const double Tolerance)
154  {
155  rIntersectionParameters.clear();
156  rIntersectionParameters.push_back(Start);
157 
158  // linearise polygon
159  const auto polygon = CurveTesselationType::ComputePolygon(
160  rGeometry, 100, Start, End);
161 
162  KRATOS_ERROR_IF(rAxis1.size() < 2)
163  << "Size of axis vector 1 is: " << rAxis1.size() << ". It needs to be at least of size 2. "
164  << "It must contain the boundaries, too. Axis vector: " << rAxis1
165  << std::endl;
166  KRATOS_ERROR_IF(rAxis2.size() < 2)
167  << "Size of axis vector 2 is: " << rAxis2.size() << ". It needs to be at least of size 2. "
168  << "It must contain the boundaries, too. Axis vector: " << rAxis1
169  << std::endl;
170 
171  bool ascending_1 = (rAxis1[0] < rAxis1[1]);
172  bool ascending_2 = (rAxis2[0] < rAxis2[1]);
173 
174  // initialize axes
175  IndexType axis_index_1, axis_index_2;
176  double min_1 = std::numeric_limits<double>::max();
177  double max_1 = std::numeric_limits<double>::lowest();
178  double min_2 = std::numeric_limits<double>::max();
179  double max_2 = std::numeric_limits<double>::lowest();
180  GetSpanIndex(rAxis1, axis_index_1, min_1, max_1, std::get<1>(polygon[0])[0], ascending_1);
181  GetSpanIndex(rAxis2, axis_index_2, min_2, max_2, std::get<1>(polygon[0])[1], ascending_2);
182 
183  // iterate through polygon and check for knot intersections
184  for (IndexType i = 1; i < polygon.size(); ++i) {
185  if (std::get<1>(polygon[i])[0] < min_1 - Tolerance) {
186  double intersection_parameter = BisectionToAxis(
187  rGeometry, min_1,
188  std::get<0>(polygon[i - 1]), std::get<0>(polygon[i]), 0, Tolerance);
189  rIntersectionParameters.push_back(intersection_parameter);
190  GetSpanIndex(rAxis1, axis_index_1, min_1, max_1, std::get<1>(polygon[i])[0], ascending_1);
191  }
192  else if (std::get<1>(polygon[i])[0] > max_1 + Tolerance) {
193  double intersection_parameter = BisectionToAxis(
194  rGeometry, max_1,
195  std::get<0>(polygon[i - 1]), std::get<0>(polygon[i]), 0, Tolerance);
196  rIntersectionParameters.push_back(intersection_parameter);
197  GetSpanIndex(rAxis1, axis_index_1, min_1, max_1, std::get<1>(polygon[i])[0], ascending_1);
198  }
199 
200  if (std::get<1>(polygon[i])[1] < min_2 - Tolerance) {
201  double intersection_parameter = BisectionToAxis(
202  rGeometry, min_2,
203  std::get<0>(polygon[i - 1]), std::get<0>(polygon[i]), 1, Tolerance);
204  rIntersectionParameters.push_back(intersection_parameter);
205  GetSpanIndex(rAxis2, axis_index_2, min_2, max_2, std::get<1>(polygon[i])[1], ascending_2);
206  }
207  else if (std::get<1>(polygon[i])[1] > max_2 + Tolerance) {
208  double intersection_parameter = BisectionToAxis(
209  rGeometry, max_2,
210  std::get<0>(polygon[i - 1]), std::get<0>(polygon[i]), 1, Tolerance);
211  rIntersectionParameters.push_back(intersection_parameter);
212  GetSpanIndex(rAxis2, axis_index_2, min_2, max_2, std::get<1>(polygon[i])[1], ascending_2);
213  }
214  }
215 
216  // Add last element if different from knot intersection.
217  if (std::abs(rIntersectionParameters[rIntersectionParameters.size() - 1] - End) > Tolerance)
218  rIntersectionParameters.push_back(End);
219 
220  // sort and delete duplicated entries
221  SortUnique(rIntersectionParameters, Tolerance);
222  }
223  };
224 } // namespace Kratos.
225 
226 #endif // KRATOS_CURVE_AXIS_INTERSECTION_INCLUDED defined
Definition: curve_axis_intersection.h:28
GeometryType::Pointer GeometryPointerType
Definition: curve_axis_intersection.h:34
std::size_t SizeType
Definition: curve_axis_intersection.h:30
GeometryType::CoordinatesArrayType CoordinatesArrayType
Definition: curve_axis_intersection.h:35
Geometry< TNodeType > GeometryType
Definition: curve_axis_intersection.h:33
std::size_t IndexType
Definition: curve_axis_intersection.h:31
static void ComputeAxisIntersection(std::vector< double > &rIntersectionParameters, const GeometryType &rGeometry, double Start, double End, const std::vector< double > &rAxis1, const std::vector< double > &rAxis2, const double Tolerance)
Definition: curve_axis_intersection.h:146
CurveTessellation< PointerVector< TNodeType > > CurveTesselationType
Definition: curve_axis_intersection.h:37
Definition: curve_tessellation.h:32
static TessellationType ComputePolygon(const GeometryType &rGeometry, const SizeType NumberOfPoints, const double Start, const double End)
Definition: curve_tessellation.h:286
Geometry base class.
Definition: geometry.h:71
virtual CoordinatesArrayType & GlobalCoordinates(CoordinatesArrayType &rResult, CoordinatesArrayType const &LocalCoordinates) const
Definition: geometry.h:2377
Short class definition.
Definition: array_1d.h:61
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_DEBUG_ERROR_IF(conditional)
Definition: exception.h:171
end
Definition: DEM_benchmarks.py:180
static double max(double a, double b)
Definition: GeometryFunctions.h:79
static double min(double a, double b)
Definition: GeometryFunctions.h:71
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31