Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CORE] Fixed issue with projection onto 2D2 line when input does not lie exactly on the line. #12637

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
27 changes: 7 additions & 20 deletions kratos/geometries/line_2d_2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1066,26 +1066,13 @@ class Line2D2 : public Geometry<TPointType>
const TPointType& r_first_point = BaseType::GetPoint(0);
const TPointType& r_second_point = BaseType::GetPoint(1);

// Project point
const double tolerance = 1e-14; // Tolerance
// Project the point on the line in global space
const auto vector_from_first_point_to_input = rPoint - r_first_point;
const auto unity_line_direction = (r_second_point - r_first_point) / Length();
const auto projection_on_line = inner_prod(vector_from_first_point_to_input, unity_line_direction);

const double length = Length();

const double length_1 = std::sqrt( std::pow(rPoint[0] - r_first_point[0], 2)
+ std::pow(rPoint[1] - r_first_point[1], 2));

const double length_2 = std::sqrt( std::pow(rPoint[0] - r_second_point[0], 2)
+ std::pow(rPoint[1] - r_second_point[1], 2));

if (length_1 <= (length + tolerance) && length_2 <= (length + tolerance)) {
rResult[0] = 2.0 * length_1/(length + tolerance) - 1.0;
} else {
if (length_1 > length_2) {
rResult[0] = 2.0 * length_1/(length + tolerance) - 1.0;
} else {
rResult[0] = -2.0 * length_1/(length + tolerance) - 1.0;
}
}
// Conversion to local space
rResult[0] = 2.0 * projection_on_line/Length() - 1.0;

return rResult ;
}
Expand Down Expand Up @@ -1409,4 +1396,4 @@ const GeometryData Line2D2<TPointType>::msGeometryData(
template<class TPointType>
const GeometryDimension Line2D2<TPointType>::msGeometryDimension(2, 1);

} // namespace Kratos.
} // namespace Kratos.
42 changes: 42 additions & 0 deletions kratos/tests/cpp_tests/geometries/test_line_2d_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,48 @@ namespace Testing {
KRATOS_EXPECT_NEAR(test_point_local_coords(2), 0.0, TOLERANCE);
}

/** Checks the point local coordinates for a given point respect to the line.
rfaasse marked this conversation as resolved.
Show resolved Hide resolved
* A point 'above' the line is selected (meaning it moved a bit in the direction normal to the line).
*/
KRATOS_TEST_CASE_IN_SUITE(Line2D2PointLocalCoordinates_NotAligned, KratosCoreGeometriesFastSuite)
{
// Create the test line
auto geom = GeneratePointsDiagonalLine2D2();

// Set the point to be checked, starting at the center and move it in the normal direction
Point test_point(0.5 - 0.1,0.5 + 0.1,0.0);

// Compute the centre local coordinates
array_1d<double, 3> test_point_local_coords;
geom->PointLocalCoordinates(test_point_local_coords, test_point);

// Since we started at the center and moved in the normal direction, we expect the local
// coordinate to be (0, 0, 0)
KRATOS_EXPECT_NEAR(test_point_local_coords(0), 0.0, TOLERANCE);
KRATOS_EXPECT_NEAR(test_point_local_coords(1), 0.0, TOLERANCE);
KRATOS_EXPECT_NEAR(test_point_local_coords(2), 0.0, TOLERANCE);
}

/** Checks the point local coordinates for a given point respect to the line.
* A point outside and not aligned with the line is selected. In this case the distance from first node is larger than the length
*/
KRATOS_TEST_CASE_IN_SUITE(Line2D2PointLocalCoordinatesOutsidePointNotAligned, KratosCoreGeometriesFastSuite)
{
// Create the test line
auto geom = GeneratePointsDiagonalLine2D2();

// Set the point to be checked (moved in the normal direction)
Point test_point(-1.5 - 0.1,-1.5 + 0.1,0.0);

// Compute the centre local coordinates
array_1d<double, 3> test_point_local_coords;
geom->PointLocalCoordinates(test_point_local_coords, test_point);

KRATOS_EXPECT_NEAR(test_point_local_coords(0), -4.0, TOLERANCE);
KRATOS_EXPECT_NEAR(test_point_local_coords(1), 0.0, TOLERANCE);
KRATOS_EXPECT_NEAR(test_point_local_coords(2), 0.0, TOLERANCE);
}

/** Tests the Jacobian determinants using 'GI_GAUSS_1' integration method.
* Tests the Jacobian determinants using 'GI_GAUSS_1' integration method.
*/
Expand Down
Loading