diff --git a/include/world_builder/features/fault.h b/include/world_builder/features/fault.h index cfbaab582..f589f3cf1 100644 --- a/include/world_builder/features/fault.h +++ b/include/world_builder/features/fault.h @@ -26,6 +26,7 @@ #include "world_builder/features/fault_models/temperature/interface.h" #include "world_builder/objects/segment.h" #include "world_builder/bounding_box.h" +#include "world_builder/objects/distance_from_surface.h" namespace WorldBuilder @@ -129,6 +130,15 @@ namespace WorldBuilder const std::vector &entry_in_output, std::vector &output) const override final; + /** + * Returns a PlaneDistances object that has the distance from and along a fault plane, + * calculated from the coordinates and the depth of the point. + */ + Objects::PlaneDistances + distance_to_feature_plane(const Point<3> &position_in_cartesian_coordinates, + const Objects::NaturalCoordinate &position_in_natural_coordinates, + const double depth) const override; + private: std::vector > default_temperature_models; std::vector > default_composition_models; diff --git a/source/world_builder/features/fault.cc b/source/world_builder/features/fault.cc index 36db5042c..3a068dc56 100644 --- a/source/world_builder/features/fault.cc +++ b/source/world_builder/features/fault.cc @@ -682,6 +682,39 @@ namespace WorldBuilder } + Objects::PlaneDistances + Fault::distance_to_feature_plane(const Point<3> &position_in_cartesian_coordinates, + const Objects::NaturalCoordinate &position_in_natural_coordinates, + const double depth) const + { + // The depth variable is the distance from the surface to the position, the depth + // coordinate is the distance from the bottom of the model to the position and + // the starting radius is the distance from the bottom of the model to the surface. + const double starting_radius = position_in_natural_coordinates.get_depth_coordinate() + depth - starting_depth; + + WBAssert(std::abs(starting_radius) > std::numeric_limits::epsilon(), "World Builder error: starting_radius can not be zero. " + << "Position = " << position_in_cartesian_coordinates[0] << ':' << position_in_cartesian_coordinates[1] << ':' << position_in_cartesian_coordinates[2] + << ", natural_coordinate.get_depth_coordinate() = " << position_in_natural_coordinates.get_depth_coordinate() + << ", depth = " << depth + << ", starting_depth " << starting_depth + ); + + const WorldBuilder::Utilities::PointDistanceFromCurvedPlanes distance_from_planes = + WorldBuilder::Utilities::distance_point_from_curved_planes(position_in_cartesian_coordinates, + position_in_natural_coordinates, + reference_point, + coordinates, + fault_segment_lengths, + fault_segment_angles, + starting_radius, + this->world->parameters.coordinate_system, + false, + this->bezier_curve); + + Objects::PlaneDistances plane_distances(distance_from_planes.distance_from_plane, distance_from_planes.distance_along_plane); + return plane_distances; + } + /** * Register plugin */ diff --git a/tests/unit_tests/approval_tests/approved/unit_test_world_builder.WorldBuilder_Features__Distance_to_Feature_Plane.txt b/tests/unit_tests/approval_tests/approved/unit_test_world_builder.WorldBuilder_Features__Distance_to_Feature_Plane.txt index e479bfd50..ebb7e5ae7 100644 --- a/tests/unit_tests/approval_tests/approved/unit_test_world_builder.WorldBuilder_Features__Distance_to_Feature_Plane.txt +++ b/tests/unit_tests/approval_tests/approved/unit_test_world_builder.WorldBuilder_Features__Distance_to_Feature_Plane.txt @@ -7,4 +7,10 @@ Test [3] = 153.282 [4] = 468.712 [5] = 139.151 +[6] = 1070.96 +[7] = 6141.53 +[8] = inf +[9] = inf +[10] = inf +[11] = inf diff --git a/tests/unit_tests/unit_test_world_builder.cc b/tests/unit_tests/unit_test_world_builder.cc index a7565be1c..c014fdefb 100644 --- a/tests/unit_tests/unit_test_world_builder.cc +++ b/tests/unit_tests/unit_test_world_builder.cc @@ -1072,11 +1072,9 @@ TEST_CASE("WorldBuilder Features: Distance to Feature Plane") approval_tests.emplace_back(plane_distances3.get_distance_from_surface()); approval_tests.emplace_back(plane_distances3.get_distance_along_surface()); - ApprovalTests::Approvals::verifyAll("Test", approval_tests); } - // call the distance_to_plane to a fault feature, as this is not implemented yet, we should be - // informed by the assertion error message. + // call the distance_to_plane to a fault feature. const std::string file_name2 = WorldBuilder::Data::WORLD_BUILDER_SOURCE_DIR + "/tests/data/fault_constant_angles_cartesian.wb"; WorldBuilder::World world2(file_name2); { @@ -1087,10 +1085,23 @@ TEST_CASE("WorldBuilder Features: Distance to Feature Plane") fault->parse_entries(world2.parameters); world2.parameters.leave_subsection(); world2.parameters.leave_subsection(); - const std::array point = {{50e3,230e3,800e3}}; - const double depth = 10e3; - CHECK_THROWS_WITH(world2.distance_to_plane(point, depth, "First fault"), - Contains("The distance_to_feature_plane is not yet implemented for the desinated object")); + const std::array point1 = {{250e3,495e3,800e3}}; + const double depth1 = 5.1e3; + auto plane_distances1 = world2.distance_to_plane(point1, depth1, "First fault"); + approval_tests.emplace_back(plane_distances1.get_distance_from_surface()); + approval_tests.emplace_back(plane_distances1.get_distance_along_surface()); + const std::array point2 = {{502e3,500e3,800e3}}; + const double depth2 = 0.45e3; + auto plane_distances2 = world2.distance_to_plane(point2, depth2, "First fault"); + approval_tests.emplace_back(plane_distances2.get_distance_from_surface()); + approval_tests.emplace_back(plane_distances2.get_distance_along_surface()); + const std::array point3 = {{502e3,500e3,800e3}}; // point 3, shallower than point2, thus distance from plane = inf + const double depth3 = 0.43e3; + auto plane_distances3 = world2.distance_to_plane(point3, depth3, "First fault"); + approval_tests.emplace_back(plane_distances3.get_distance_from_surface()); + approval_tests.emplace_back(plane_distances3.get_distance_along_surface()); + + ApprovalTests::Approvals::verifyAll("Test", approval_tests); } }