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.
projection_nurbs_geometry_utilities.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: Thomas Oberbichler
11 // Tobias Teschemacher
12 //
13 
14 #if !defined(KRATOS_PROJECTION_NURBS_GEOMETRY_UTILITIES_H_INCLUDED)
15 #define KRATOS_PROJECTION_NURBS_GEOMETRY_UTILITIES_H_INCLUDED
16 
17 // System includes
18 
19 // External includes
20 
21 // Project includes
22 #include "geometries/geometry.h"
23 #include "containers/array_1d.h"
24 
25 namespace Kratos
26 {
27 template<int TDimension, class TPointType> class NurbsSurfaceGeometry;
29 {
30 public:
31 
33 
34  /*
35  * @brief Returns the projection of a point onto a Nurbs curve
36  * geometry using the Newton-Rapshon iterative method
37  * @param rProjectedPointLoaclCoordinates Intial guess for the Newton-Rapshon algorithm
38  * overwritten by the local coordinates of the projected point onto
39  * the Nurbs curve geometry
40  * @param rPoint The point to be projected onto the Nurbs curve geometry
41  * This is overwritten by the Cartesian coordinates of the projected
42  * point in case the projection is successful
43  * @param rProjectedPointGlobalCoordinates The projection onto the Nurbs curve geometry
44  * @param rNurbsCurve The Nurbs curve geometry onto which the point is
45  * to be projected
46  * @param MaxIterations Maximum number of iterations for the Newton-Rapshon
47  * algorithm
48  * @param Accuracy Accuracy for the the Newton-Rapshon algorithm
49  */
50  template <class TPointType>
51  static bool NewtonRaphsonCurve(
52  CoordinatesArrayType& rProjectedPointLocalCoordinates,
53  const CoordinatesArrayType& rPointGlobalCoordinatesCoordinates,
54  CoordinatesArrayType& rProjectedPointGlobalCoordinates,
55  const Geometry<TPointType>& rGeometry,
56  const int MaxIterations = 20,
57  const double Accuracy = 1e-6)
58  {
59  // Intialize variables
60  double residual, delta_t;
61 
62  std::vector<array_1d<double, 3>> derivatives(3);
63  array_1d<double, 3> distance_vector;
64 
65  bool projection_reset_to_boundary = false;
66 
67  // Loop over all Newton-Raphson iterations
68  for (int i = 0; i < MaxIterations; ++i)
69  {
70  // Compute the position, the base and the acceleration vector
71  rGeometry.GlobalSpaceDerivatives(
72  derivatives,
73  rProjectedPointLocalCoordinates,
74  2);
75  rProjectedPointGlobalCoordinates = derivatives[0];
76 
77  // Compute the distance vector between the point and its
78  // projection on the curve
79  distance_vector = rProjectedPointGlobalCoordinates - rPointGlobalCoordinatesCoordinates;
80  if (norm_2(distance_vector) < Accuracy)
81  return true;
82 
83  // Compute the residual
84  residual = inner_prod(distance_vector, derivatives[1]);
85  if (std::abs(residual) < Accuracy)
86  return true;
87 
88  // Compute the increment
89  delta_t = residual / (inner_prod(derivatives[2], distance_vector) + pow(norm_2(derivatives[1]), 2));
90 
91  // Increment the parametric coordinate
92  rProjectedPointLocalCoordinates[0] -= delta_t;
93 
94  // Check if the increment is too small and if yes return true
95  if (norm_2(delta_t * derivatives[1]) < Accuracy)
96  return true;
97 
98  // Check if the parameter gets out of its interval of definition and if so clamp it
99  // back to the boundaries
100  int check = rGeometry.ClosestPointLocalToLocalSpace(
101  rProjectedPointLocalCoordinates, rProjectedPointLocalCoordinates);
102  if (check == 0) {
103  if (projection_reset_to_boundary) { return false; }
104  else { projection_reset_to_boundary = true; }
105  }
106  }
107 
108  // Return false if the Newton-Raphson iterations did not converge
109  return false;
110  }
111 
112  /*
113  * @brief Returns the projection of a point onto a Nurbs surface
114  * geometry using the Newton-Rapshon iterative method
115  * @param rProjectedPointLocalCoordinates Intial guess for the Newton-Rapshon algorithm
116  * overwritten by the local coordinates of the projected point onto
117  * the Nurbs surface geometry
118  * @param rPoint The point to be projected onto the Nurbs surface geometry
119  * This is overwritten by the Cartesian coordinates of the projected
120  * point in case the projection is successful
121  * @param rResult The projection onto the Nurbs surface geometry
122  * @param rNurbsCurve The Nurbs curve geometry onto which the point is
123  * to be projected
124  * @param MaxIterations Maximum number of iterations for the Newton-Rapshon
125  * algorithm
126  * @param Accuracy Accuracy for the the Newton-Rapshon algorithm
127  */
128  template <int TDimension, class TPointType>
129  static bool NewtonRaphsonSurface(
130  CoordinatesArrayType& rProjectedPointLocalCoordinates,
131  const CoordinatesArrayType& rPointGlobalCoordinates,
132  CoordinatesArrayType& rProjectedPointGlobalCoordinates,
134  const int MaxIterations = 20,
135  const double Accuracy = 1e-6)
136  {
137  // Initialize variables
138  bool is_first_row_zero, is_second_row_zero, is_first_column_zero, is_second_column_zero, is_system_invertible;
139  double d_u = 0.0;
140  double d_v = 0.0;
141  double xi_cos, eta_cos, residual_u, residual_v, j_00, j_01, j_11, det_j;
142 
143  // Loop over all the Newton-Raphson iterations
144  for (int i = 0; i < MaxIterations; i++) {
145 
146  // Compute the position, the base and the acceleration vectors
147  std::vector<array_1d<double, 3>> s;
148  rNurbsSurface.GlobalSpaceDerivatives(s, rProjectedPointLocalCoordinates, 2);
149  rProjectedPointGlobalCoordinates = s[0];
150 
151  // Compute the distance vector
152  const array_1d<double, 3> distance_vector = s[0] - rPointGlobalCoordinates;
153 
154  // Compute the distance
155  const double distance = norm_2(distance_vector);
156  if (distance < Accuracy)
157  return true;
158 
159  // Compute the residuals along both parametric directions
160  residual_u = -inner_prod(s[1], distance_vector);
161  residual_v = -inner_prod(s[2], distance_vector);
162 
163  // Compute the cosine with respect to the u-parametric coordinate
164  xi_cos = std::abs(residual_u) / norm_2(s[1]) / norm_2(distance_vector);
165 
166  // Compute the cosine with respect to the v-parametric coordinate
167  eta_cos = std::abs(residual_v) / norm_2(s[2]) / norm_2(distance_vector);
168 
169  // Check the orthogonality condition
170  if (xi_cos < Accuracy && eta_cos < Accuracy)
171  return true;
172 
173  // Compute the Jacobian of the nonlinear system
174  j_00 = inner_prod(s[1], s[1]) + inner_prod(s[3], distance_vector);
175  j_01 = inner_prod(s[1], s[2]) + inner_prod(s[4], distance_vector);
176  j_11 = inner_prod(s[2], s[2]) + inner_prod(s[5], distance_vector);
177 
178  // Check for singularities otherwise update the parametric coordinates as usual
179  is_first_row_zero = false;
180  if ((std::abs(j_00) < Accuracy && std::abs(j_01) < Accuracy)) {
181  is_first_row_zero = true;
182  }
183  is_second_row_zero = false;
184  if (std::abs(j_01) < Accuracy && fabs(j_11) < Accuracy) {
185  is_second_row_zero = true;
186  }
187  is_first_column_zero = false;
188  if ((std::abs(j_00) < Accuracy && std::abs(j_01) < Accuracy)) {
189  is_first_column_zero = true;
190  }
191  is_second_column_zero = false;
192  if ((std::abs(j_01) < Accuracy && std::abs(j_11) < Accuracy)) {
193  is_second_column_zero = true;
194  }
195 
196  // Check if the system is solvable by checking the condition of the diagonal entries
197  is_system_invertible = true;
198  if (is_first_row_zero || is_second_row_zero || is_first_column_zero || is_second_column_zero) {
199  is_system_invertible = false;
200  }
201 
202  // Solve the 2x2 linear equation system and take into account special cases where singularities occur
203  if (is_system_invertible) {
204  det_j = j_00 * j_11 - j_01 * j_01;
205  d_u = -(residual_v * j_01 - residual_u * j_11) / det_j;
206  d_v = -(residual_u * j_01 - residual_v * j_00) / det_j;
207  }
208  else {
209  if (is_first_row_zero) {
210  d_u = residual_v / j_11;
211  d_v = 0.0;
212  }
213  else if (is_second_row_zero) {
214  d_u = residual_u / j_00;
215  d_v = 0.0;
216  }
217  else if (is_first_column_zero) {
218  d_v = (residual_u + residual_v) / (j_01 + j_11);
219  d_u = 0.0;
220  }
221  else if (is_second_column_zero) {
222  d_u = (residual_u + residual_v) / (j_00 + j_01);
223  d_v = 0.0;
224  }
225  }
226 
227  // Check if the step size is too small
228  if (norm_2(d_u * s[1] + d_v * s[2]) < Accuracy)
229  return true;
230 
231  // Update the parametric coordinates
232  rProjectedPointLocalCoordinates[0] += d_u;
233  rProjectedPointLocalCoordinates[1] += d_v;
234 
235  // Check if the parametric coordinates get out of their interval of definition
236  // and if so clamp them back to their boundaries
237  rNurbsSurface.DomainIntervalU().IsInside(rProjectedPointLocalCoordinates[0]);
238  rNurbsSurface.DomainIntervalV().IsInside(rProjectedPointLocalCoordinates[1]);
239  }
240 
241  return false;
242  }
243 };
244 } // namespace Kratos
245 
246 #endif // KRATOS_PROJECTION_NURBS_GEOMETRY_UTILITIES_H_INCLUDED
Geometry base class.
Definition: geometry.h:71
virtual int ClosestPointLocalToLocalSpace(const CoordinatesArrayType &rPointLocalCoordinates, CoordinatesArrayType &rClosestPointLocalCoordinates, const double Tolerance=std::numeric_limits< double >::epsilon()) const
Calculates the closes point projection This method calculates the closest point projection of a point...
Definition: geometry.h:2792
virtual void GlobalSpaceDerivatives(std::vector< CoordinatesArrayType > &rGlobalSpaceDerivatives, const CoordinatesArrayType &rLocalCoordinates, const SizeType DerivativeOrder) const
This method maps from dimension space to working space and computes the number of derivatives at the ...
Definition: geometry.h:2473
bool IsInside(double &ParameterT) const
Definition: nurbs_interval.h:143
Definition: nurbs_surface_geometry.h:38
void GlobalSpaceDerivatives(std::vector< CoordinatesArrayType > &rGlobalSpaceDerivatives, const CoordinatesArrayType &rLocalCoordinates, const SizeType DerivativeOrder) const override
Definition: nurbs_surface_geometry.h:742
NurbsInterval DomainIntervalU() const
Definition: nurbs_surface_geometry.h:407
NurbsInterval DomainIntervalV() const
Definition: nurbs_surface_geometry.h:417
Definition: projection_nurbs_geometry_utilities.h:29
array_1d< double, 3 > CoordinatesArrayType
Definition: projection_nurbs_geometry_utilities.h:32
static bool NewtonRaphsonSurface(CoordinatesArrayType &rProjectedPointLocalCoordinates, const CoordinatesArrayType &rPointGlobalCoordinates, CoordinatesArrayType &rProjectedPointGlobalCoordinates, const NurbsSurfaceGeometry< TDimension, TPointType > &rNurbsSurface, const int MaxIterations=20, const double Accuracy=1e-6)
Definition: projection_nurbs_geometry_utilities.h:129
static bool NewtonRaphsonCurve(CoordinatesArrayType &rProjectedPointLocalCoordinates, const CoordinatesArrayType &rPointGlobalCoordinatesCoordinates, CoordinatesArrayType &rProjectedPointGlobalCoordinates, const Geometry< TPointType > &rGeometry, const int MaxIterations=20, const double Accuracy=1e-6)
Definition: projection_nurbs_geometry_utilities.h:51
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
residual
Definition: hinsberg_optimization_4.py:433
float delta_t
Definition: rotatingcone_PureConvectionBenchmarking.py:129
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31