Skip to content

Commit

Permalink
interface for the distance to a feature's plane
Browse files Browse the repository at this point in the history
  • Loading branch information
lhy11009 committed Dec 19, 2022
1 parent d46936c commit 5d612a5
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/world_builder/features/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "world_builder/grains.h"
#include "world_builder/utilities.h"
#include "world_builder/objects/distance_from_surface.h"

namespace WorldBuilder
{
Expand Down Expand Up @@ -107,6 +108,17 @@ namespace WorldBuilder
*/
static std::unique_ptr<Interface> create(const std::string &name, WorldBuilder::World *world);

/**
* Returns a PlaneDistances object that has the distance from and along a feature plane,
* caculated from the coordinates and the depth of the point.
*/
virtual
Objects::PlaneDistances
distance_to_feature_plane(const Point<3> &position_in_cartesian_coordinates,
const Objects::NaturalCoordinate &position_in_natural_coordinates,
const double depth) const;


protected:
/**
* A pointer to the world class to retrieve variables.
Expand Down
11 changes: 11 additions & 0 deletions include/world_builder/features/subducting_plate.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "world_builder/features/subducting_plate_models/temperature/interface.h"
#include "world_builder/types/segment.h"
#include "world_builder/bounding_box.h"
#include "world_builder/objects/distance_from_surface.h"


namespace WorldBuilder
Expand Down Expand Up @@ -129,6 +130,16 @@ namespace WorldBuilder
const std::vector<size_t> &entry_in_output,
std::vector<double> &output) const override final;

/**
* Returns a PlaneDistances object that has the distance from and along a subducting plate plane,
* caculated 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<std::shared_ptr<Features::SubductingPlateModels::Temperature::Interface> > default_temperature_models;
std::vector<std::shared_ptr<Features::SubductingPlateModels::Composition::Interface> > default_composition_models;
Expand Down
65 changes: 65 additions & 0 deletions include/world_builder/objects/distance_from_surface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright (C) 2018 - 2021 by the authors of the World Builder code.
This file is part of the World Builder.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

// define a new struct
#ifndef WORLD_BUILDER_OBJECTSS_DISTANCE_FROM_SURFACE_H
#define WORLD_BUILDER_OBJECTSS_DISTANCE_FROM_SURFACE_H

namespace WorldBuilder
{
namespace Objects
{
class PlaneDistances
{
public:

/**
* Constructor to create an PlaneDistances object from the distance
* from and along the surface of plane
*/
PlaneDistances(const double d0, const double d1)
:
distance_from_surface(d0),
distance_along_surface(d1)
{}

/**
* Function to get the distance from the surface
*/
double get_distance_from_surface();

/**
* Function to get the distance along the surface
*/
double get_distance_along_surface();

private:
/**
* the distance from the surface of the plane
*/
double distance_from_surface;
/**
* the distance along the surface of the plane
*/
double distance_along_surface;
};
}
}

#endif
11 changes: 11 additions & 0 deletions include/world_builder/world.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include "world_builder/grains.h"
#include "world_builder/parameters.h"
#include "world_builder/utilities.h"
#include "world_builder/objects/distance_from_surface.h"

#include <random>

Expand All @@ -30,6 +32,7 @@
*/
namespace WorldBuilder
{

namespace Features
{
class Interface;
Expand Down Expand Up @@ -188,6 +191,14 @@ namespace WorldBuilder
const double depth,
const unsigned int composition_number,
size_t number_of_grains) const;
/**
* Returns a PlaneDistances object that has the distance from and along a feature plane,
* caculated from the coordinates and the depth of the point.
*/
Objects::PlaneDistances
distance_to_plane(const std::array<double, 3> &point,
const double depth,
const std::string name) const;

/**
* The MPI rank. Set to zero if MPI is not available.
Expand Down
8 changes: 8 additions & 0 deletions source/world_builder/features/interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ namespace WorldBuilder
return get_factory_map().at(lower_case_name)->create(world);
}

Objects::PlaneDistances
Interface::distance_to_feature_plane(const Point<3> &,
const Objects::NaturalCoordinate &,
const double) const
{
WBAssertThrow(false, "The distance_to_feature_plane is not yet implemented for the desinated object");
}

} // namespace Features
} // namespace WorldBuilder

34 changes: 34 additions & 0 deletions source/world_builder/features/subducting_plate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,40 @@ namespace WorldBuilder

}

Objects::PlaneDistances
SubductingPlate::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<double>::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
);

WorldBuilder::Utilities::PointDistanceFromCurvedPlanes distance_from_planes =
WorldBuilder::Utilities::distance_point_from_curved_planes(position_in_cartesian_coordinates,
position_in_natural_coordinates,
reference_point,
coordinates,
slab_segment_lengths,
slab_segment_angles,
starting_radius,
this->world->parameters.coordinate_system,
false,
this->x_spline,
this->y_spline);

Objects::PlaneDistances plane_distances(distance_from_planes.distance_from_plane, distance_from_planes.distance_along_plane);
return plane_distances;
}

/**
* Register plugin
*/
Expand Down
36 changes: 36 additions & 0 deletions source/world_builder/objects/distance_from_surface.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright (C) 2018 - 2021 by the authors of the World Builder code.
This file is part of the World Builder.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "world_builder/objects/distance_from_surface.h"

namespace WorldBuilder
{
namespace Objects
{
double PlaneDistances::get_distance_from_surface()
{
return this->distance_from_surface;
}

double PlaneDistances::get_distance_along_surface()
{
return this->distance_along_surface;
}
}
}
32 changes: 32 additions & 0 deletions source/world_builder/world.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
#include "world_builder/types/plugin_system.h"
#include "world_builder/types/point.h"
#include "world_builder/gravity_model/interface.h"
#include "world_builder/features/subducting_plate.h"

#include <iostream>
#include <world_builder/coordinate_system.h>
#include <world_builder/objects/distance_from_surface.h>

#ifdef WB_WITH_MPI
#define OMPI_SKIP_MPICXX 1
Expand Down Expand Up @@ -413,5 +415,35 @@ namespace WorldBuilder
return random_number_engine;
}

Objects::PlaneDistances
World::distance_to_plane(const std::array<double, 3> &point_,
const double depth,
const std::string name) const
{
// We receive the cartesian points from the user.
Point<3> point(point_,cartesian);

WBAssert(!this->limit_debug_consistency_checks || this->parameters.coordinate_system->natural_coordinate_system() == cartesian
|| approx(depth, this->parameters.coordinate_system->max_model_depth()-sqrt(point_[0]*point_[0]+point_[1]*point_[1]+point_[2]*point_[2])),
"Inconsistent input. Please check whether the radius in the sperhical coordiantes is consistent with the radius of the planet as defined "
<< "in the program that uses the Geodynamic World Builder. "
<< "Depth = " << depth << ", radius = " << this->parameters.coordinate_system->max_model_depth()
<< ", point = " << point_[0] << " " << point_[1] << " " << point_[2]
<< ", radius-point.norm() = " << this->parameters.coordinate_system->max_model_depth()-sqrt(point_[0]*point_[0]+point_[1]*point_[1]+point_[2]*point_[2]));

Objects::NaturalCoordinate natural_coordinate = Objects::NaturalCoordinate(point,*(this->parameters.coordinate_system));

Objects::PlaneDistances plane_distances(0.0, 0.0);
for (auto &&it : this->parameters.features)
{
if (it->get_name() == name)
{
plane_distances = it->distance_to_feature_plane(point, natural_coordinate, depth);
break;
}
}
return plane_distances;
}

} // namespace WorldBuilder

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Test


[0] = 7141.78
[1] = 70.7107
[2] = 618.443
[3] = 13.5623
[4] = inf
[5] = inf

55 changes: 55 additions & 0 deletions tests/unit_tests/unit_test_world_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ TEST_CASE("WorldBuilder Utilities: Point in polygon")
}



TEST_CASE("WorldBuilder Utilities: Natural Coordinate")
{
std::vector<double> approval_tests;
Expand Down Expand Up @@ -1041,6 +1042,60 @@ TEST_CASE("WorldBuilder Features: Interface")

}

TEST_CASE("WorldBuilder Features: Distance to Feature Plane")
{
std::vector<double> approval_tests;

// call the distance_to_plane to a subducting plate feature,
std::string file_name = WorldBuilder::Data::WORLD_BUILDER_SOURCE_DIR + "/tests/data/subducting_plate_constant_angles_cartesian.wb";
WorldBuilder::World world1(file_name);
{
std::unique_ptr<Features::Interface> subducting_plate = Features::Interface::create("Subducting Plate", &world1);

world1.parameters.enter_subsection("features");
world1.parameters.enter_subsection("2");
subducting_plate->parse_entries(world1.parameters);
world1.parameters.leave_subsection();
world1.parameters.leave_subsection();
const std::array<double, 3> point1 = {250e3,495e3,800e3};
const double depth1 = 5.1e3;
auto plane_distances1 = world1.distance_to_plane(point1, depth1, "First subducting plate");
approval_tests.emplace_back(plane_distances1.get_distance_from_surface());
approval_tests.emplace_back(plane_distances1.get_distance_along_surface());
const std::array<double, 3> point2 = {502e3,500e3,800e3};
const double depth2 = 0.45e3;
auto plane_distances2 = world1.distance_to_plane(point2, depth2, "First subducting plate");
approval_tests.emplace_back(plane_distances2.get_distance_from_surface());
approval_tests.emplace_back(plane_distances2.get_distance_along_surface());
const std::array<double, 3> point3 = {502e3,500e3,800e3}; // point 3, shallower than point2, thus distance from plane = inf
const double depth3 = 0.43e3;
auto plane_distances3 = world1.distance_to_plane(point3, depth3, "First subducting plate");
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.
std::string file_name2 = WorldBuilder::Data::WORLD_BUILDER_SOURCE_DIR + "/tests/data/fault_constant_angles_cartesian.wb";
WorldBuilder::World world2(file_name2);
{
std::unique_ptr<Features::Interface> fault = Features::Interface::create("Fault", &world2);

world2.parameters.enter_subsection("features");
world2.parameters.enter_subsection("2");
fault->parse_entries(world2.parameters);
world2.parameters.leave_subsection();
world2.parameters.leave_subsection();
const std::array<double, 3> 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"));
}
}


TEST_CASE("WorldBuilder Features: Continental Plate")
{
std::vector<double> approval_tests;
Expand Down

0 comments on commit 5d612a5

Please sign in to comment.