38 using namespace Utilities;
47 this->
name =
"subducting plate";
76 Pointer((path +
"/body").c_str()).Set(declarations,
"object");
77 Pointer((path +
"/body/model").c_str()).Set(declarations,
"subducting plate");
78 Pointer((path +
"/body/name").c_str()).Set(declarations,
"${1:My Subducting Plate}");
79 Pointer((path +
"/body/coordinates").c_str()).Create(declarations).SetArray();
80 Pointer((path +
"/body/temperature models").c_str()).Create(declarations).SetArray();
81 Pointer((path +
"/body/composition models").c_str()).Create(declarations).SetArray();
88 const std::string &parent_name,
89 const std::vector<std::string> &required_entries)
93 if (parent_name ==
"items")
99 prm.
declare_entry(
"",
Types::Object(required_entries),
"Subducting slab object. Requires properties `model` and `coordinates`.");
104 "The depth to which this feature is present");
106 "The depth to which this feature is present");
108 "The depth to which this feature is present");
115 prm.
declare_entry(
"segments",
Types::Array(
Types::Segment(0,
Point<2>(0,0,
invalid),
Point<2>(0,0,
invalid),
Point<2>(0,0,
invalid),
120 "The depth to which this feature is present");
124 "A list of temperature models.");
127 "A list of composition models.");
130 "A list of grains models.");
133 "A list of velocity models.");
135 if (parent_name !=
"items")
145 "The coordinate which should be overwritten");
156 this->
name = prm.
get<std::string>(
"name");
158 std::string tag = prm.
get<std::string>(
"tag");
161 tag =
"subducting plate";
205 std::vector<std::unique_ptr<Features::SubductingPlate> > sections_vector;
209 for (
unsigned int i_section = 0; i_section < n_sections; ++i_section)
212 for (
unsigned int i_sector = 0; i_sector < sections_vector.size(); ++i_sector)
216 const unsigned int change_coord_number = prm.
get<
unsigned int>(
"coordinate");
219 <<
"', trying to change the section of coordinate " << change_coord_number
220 <<
" while only " <<
segment_vector.size() <<
" coordinates are defined.");
222 std::vector<std::shared_ptr<Features::SubductingPlateModels::Temperature::Interface> > local_default_temperature_models;
223 std::vector<std::shared_ptr<Features::SubductingPlateModels::Composition::Interface> > local_default_composition_models;
224 std::vector<std::shared_ptr<Features::SubductingPlateModels::Grains::Interface> > local_default_grains_models;
225 std::vector<std::shared_ptr<Features::SubductingPlateModels::Velocity::Interface> > local_default_velocity_models;
227 if (!prm.
get_shared_pointers<Features::SubductingPlateModels::Temperature::Interface>(
"temperature models", local_default_temperature_models))
233 if (!prm.
get_shared_pointers<Features::SubductingPlateModels::Composition::Interface>(
"composition models", local_default_composition_models))
239 if (!prm.
get_shared_pointers<Features::SubductingPlateModels::Grains::Interface>(
"grains models", local_default_grains_models))
245 if (!prm.
get_shared_pointers<Features::SubductingPlateModels::Velocity::Interface>(
"velocity models", local_default_velocity_models))
252 Features::SubductingPlateModels::Composition::Interface,
253 Features::SubductingPlateModels::Grains::Interface,
254 Features::SubductingPlateModels::Velocity::Interface> >(
"segments", local_default_temperature_models, local_default_composition_models, local_default_grains_models, local_default_velocity_models);
258 "Error: There are not the same amount of segments in section with coordinate " << change_coord_number
259 <<
" (" <<
segment_vector[change_coord_number].size() <<
" segments) as in the default segment (" 260 << default_segment_vector.size() <<
" segments). This is not allowed.");
264 for (
unsigned int i = 0; i <
segment_vector[change_coord_number].size(); ++i)
270 for (
unsigned int j = 0; j <
segment_vector[change_coord_number][i].temperature_systems.size(); ++j)
274 segment_vector[change_coord_number][i].temperature_systems[j]->parse_entries(prm);
284 for (
unsigned int j = 0; j <
segment_vector[change_coord_number][i].composition_systems.size(); ++j)
288 segment_vector[change_coord_number][i].composition_systems[j]->parse_entries(prm);
297 for (
unsigned int j = 0; j <
segment_vector[change_coord_number][i].grains_systems.size(); ++j)
301 segment_vector[change_coord_number][i].grains_systems[j]->parse_entries(prm);
310 for (
unsigned int j = 0; j <
segment_vector[change_coord_number][i].velocity_systems.size(); ++j)
314 segment_vector[change_coord_number][i].velocity_systems[j]->parse_entries(prm);
336 for (
unsigned int i = 0; i < default_segment_vector.size(); ++i)
342 for (
unsigned int j = 0; j < default_segment_vector[i].temperature_systems.size(); ++j)
346 default_segment_vector[i].temperature_systems[j]->
parse_entries(prm);
356 for (
unsigned int j = 0; j < default_segment_vector[i].composition_systems.size(); ++j)
360 default_segment_vector[i].composition_systems[j]->
parse_entries(prm);
370 for (
unsigned int j = 0; j < default_segment_vector[i].grains_systems.size(); ++j)
374 default_segment_vector[i].grains_systems[j]->
parse_entries(prm);
383 for (
unsigned int j = 0; j < default_segment_vector[i].velocity_systems.size(); ++j)
387 default_segment_vector[i].velocity_systems[j]->
parse_entries(prm);
409 double local_total_slab_length = 0;
440 auto compare_x_coordinate = [](
auto p1,
auto p2)
449 auto compare_y_coordinate = [](
auto p1,
auto p2)
501 const std::vector<std::array<unsigned int,3>> &
properties,
502 const double gravity_norm,
503 const std::vector<size_t> &entry_in_output,
504 std::vector<double> &output)
const 511 WBAssert(std::abs(starting_radius) > std::numeric_limits<double>::epsilon(),
"World Builder error: starting_radius can not be zero. " 512 <<
"Position = " << position_in_cartesian_coordinates[0] <<
':' << position_in_cartesian_coordinates[1] <<
':' << position_in_cartesian_coordinates[2]
513 <<
", position_in_natural_coordinates.get_depth_coordinate() = " << position_in_natural_coordinates.
get_depth_coordinate()
514 <<
", depth = " << depth
535 position_in_natural_coordinates,
548 const size_t current_section = distance_from_planes.
section;
549 const size_t next_section = current_section + 1;
550 const size_t current_segment = distance_from_planes.
segment;
554 if (abs(distance_from_plane) < std::numeric_limits<double>::infinity() || (distance_along_plane) < std::numeric_limits<double>::infinity())
566 const double thickness_local = thickness_up + segment_fraction * (thickness_down - thickness_up);
569 if (std::fabs(thickness_local) < 2.0 * std::numeric_limits<double>::epsilon())
581 const double top_truncation_local = top_truncation_up + segment_fraction * (top_truncation_down - top_truncation_up);
584 if (thickness_local < top_truncation_local)
591 if (distance_from_plane >= top_truncation_local &&
592 distance_from_plane <= thickness_local &&
593 distance_along_plane >= 0 &&
594 distance_along_plane <= max_slab_length)
598 for (
unsigned int i_property = 0; i_property <
properties.size(); ++i_property)
604 double temperature_current_section = output[entry_in_output[i_property]];
605 double temperature_next_section = output[entry_in_output[i_property]];
607 for (
const auto &temperature_model:
segment_vector[current_section][current_segment].temperature_systems)
609 temperature_current_section = temperature_model->get_temperature(position_in_cartesian_coordinates,
612 temperature_current_section,
615 distance_from_planes,
616 additional_parameters);
618 WBAssert(!std::isnan(temperature_current_section),
"Temperature is not a number: " << temperature_current_section
619 <<
", based on a temperature model with the name " << temperature_model->get_name() <<
", in feature " << this->
name);
620 WBAssert(std::isfinite(temperature_current_section),
"Temperature is not a finite: " << temperature_current_section
621 <<
", based on a temperature model with the name " << temperature_model->get_name() <<
", in feature " << this->
name);
625 for (
const auto &temperature_model:
segment_vector[next_section][current_segment].temperature_systems)
627 temperature_next_section = temperature_model->get_temperature(position_in_cartesian_coordinates,
630 temperature_next_section,
633 distance_from_planes,
634 additional_parameters);
636 WBAssert(!std::isnan(temperature_next_section),
"Temperature is not a number: " << temperature_next_section
637 <<
", based on a temperature model with the name " << temperature_model->get_name() <<
", in feature " << this->
name);
638 WBAssert(std::isfinite(temperature_next_section),
"Temperature is not a finite: " << temperature_next_section
639 <<
", based on a temperature model with the name " << temperature_model->get_name() <<
", in feature " << this->
name);
644 output[entry_in_output[i_property]] = temperature_current_section + section_fraction * (temperature_next_section - temperature_current_section);
649 double composition_current_section = output[entry_in_output[i_property]];
650 double composition_next_section = output[entry_in_output[i_property]];
652 for (
const auto &composition_model:
segment_vector[current_section][current_segment].composition_systems)
654 composition_current_section = composition_model->get_composition(position_in_cartesian_coordinates,
657 composition_current_section,
660 distance_from_planes,
661 additional_parameters);
663 WBAssert(!std::isnan(composition_current_section),
"Composition_current_section is not a number: " << composition_current_section
664 <<
", based on a composition model with the name " << composition_model->get_name() <<
", in feature " << this->
name);
665 WBAssert(std::isfinite(composition_current_section),
"Composition_current_section is not a finite: " << composition_current_section
666 <<
", based on a composition model with the name " << composition_model->get_name() <<
", in feature " << this->
name);
670 for (
const auto &composition_model:
segment_vector[next_section][current_segment].composition_systems)
672 composition_next_section = composition_model->get_composition(position_in_cartesian_coordinates,
675 composition_next_section,
678 distance_from_planes,
679 additional_parameters);
681 WBAssert(!std::isnan(composition_next_section),
"Composition_next_section is not a number: " << composition_next_section
682 <<
", based on a composition model with the name " << composition_model->get_name() <<
", in feature " << this->
name);
683 WBAssert(std::isfinite(composition_next_section),
"Composition_next_section is not a finite: " << composition_next_section
684 <<
", based on a composition model with the name " << composition_model->get_name() <<
", in feature " << this->
name);
689 output[entry_in_output[i_property]] = composition_current_section + section_fraction * (composition_next_section - composition_current_section);
698 for (
const auto &grains_model:
segment_vector[current_section][current_segment].grains_systems)
700 grains_current_section = grains_model->get_grains(position_in_cartesian_coordinates,
703 grains_current_section,
706 distance_from_planes,
707 additional_parameters);
711 for (
const auto &grains_model:
segment_vector[next_section][current_segment].grains_systems)
713 grains_next_section = grains_model->get_grains(position_in_cartesian_coordinates,
719 distance_from_planes,
720 additional_parameters);
725 for (
size_t i = 0; i < grains.
sizes.size(); i++)
727 grains.
sizes[i] = grains_current_section.
sizes[i] + section_fraction * (grains_next_section.
sizes[i] - grains_current_section.
sizes[i]);
733 const glm::quaternion::quat quat_current = glm::quaternion::quat_cast(grains_current_section.
rotation_matrices[i]);
734 const glm::quaternion::quat quat_next = glm::quaternion::quat_cast(grains_next_section.
rotation_matrices[i]);
736 const glm::quaternion::quat quat_average = glm::quaternion::slerp(quat_current,quat_next,section_fraction);
741 grains.
unroll_into(output,entry_in_output[i_property]);
746 output[entry_in_output[i_property]] =
static_cast<double>(
tag_index);
751 std::array<double,3> velocity_current_section;
752 velocity_current_section[0] = output[entry_in_output[i_property]];
753 velocity_current_section[1] = output[entry_in_output[i_property]+1];
754 velocity_current_section[2] = output[entry_in_output[i_property]]+2;
755 std::array<double,3> velocity_next_section = velocity_current_section;
757 for (
const auto &velocity_model:
segment_vector[current_section][current_segment].velocity_systems)
759 velocity_current_section = velocity_model->get_velocity(position_in_cartesian_coordinates,
762 velocity_current_section,
765 distance_from_planes,
766 additional_parameters);
775 for (
const auto &velocity_model:
segment_vector[next_section][current_segment].velocity_systems)
777 velocity_next_section = velocity_model->get_velocity(position_in_cartesian_coordinates,
780 velocity_next_section,
783 distance_from_planes,
784 additional_parameters);
794 output[entry_in_output[i_property]] = velocity_current_section[0] + section_fraction * (velocity_next_section[0] - velocity_current_section[0]);
795 output[entry_in_output[i_property]+1] = velocity_current_section[1] + section_fraction * (velocity_next_section[1] - velocity_current_section[1]);
796 output[entry_in_output[i_property]+2] = velocity_current_section[2] + section_fraction * (velocity_next_section[2] - velocity_current_section[2]);
802 "Internal error: Unimplemented property provided. " <<
803 "Only temperature (1), composition (2), grains (3), tag (4) or velocity (5) are allowed. " 804 "Provided property number was: " <<
properties[i_property][0]);
818 const double depth)
const 825 WBAssert(std::abs(starting_radius) > std::numeric_limits<double>::epsilon(),
"World Builder error: starting_radius can not be zero. " 826 <<
"Position = " << position_in_cartesian_coordinates[0] <<
':' << position_in_cartesian_coordinates[1] <<
':' << position_in_cartesian_coordinates[2]
827 <<
", natural_coordinate.get_depth_coordinate() = " << position_in_natural_coordinates.
get_depth_coordinate()
828 <<
", depth = " << depth
834 position_in_natural_coordinates,
844 Objects::PlaneDistances plane_distances(distance_from_planes.distance_from_plane, distance_from_planes.distance_along_plane);
845 return plane_distances;
double maximum_total_slab_length
void parse_entries(Parameters &prm) override final
std::array< double, 2 > get_surface_coordinates() const
double get_depth_coordinate() const
size_t add_vector_unique(std::vector< std::string > &vector, const std::string &add_string)
#define WB_REGISTER_FEATURE(classname, name)
void enter_subsection(const std::string &name)
static void declare_entries(Parameters &prm, const std::string &parent_name, const std::vector< std::string > &required_entries)
std::vector< std::shared_ptr< Features::SubductingPlateModels::Grains::Interface > > default_grains_models
Point< 2 > reference_point
std::vector< std::vector< Point< 2 > > > slab_segment_angles
virtual void parse_entries(Parameters &prm)=0
bool get_shared_pointers(const std::string &name, std::vector< std::shared_ptr< T > > &)
std::vector< double > sizes
static void make_snippet(Parameters &prm)
std::vector< std::shared_ptr< Features::SubductingPlateModels::Composition::Interface > > default_composition_models
std::vector< std::vector< Point< 2 > > > slab_segment_top_truncation
double fraction_of_section
std::pair< Point< spacedim >, Point< spacedim > > & get_boundary_points()
std::vector< std::vector< Objects::Segment< Features::SubductingPlateModels::Temperature::Interface, Features::SubductingPlateModels::Composition::Interface, Features::SubductingPlateModels::Grains::Interface, Features::SubductingPlateModels::Velocity::Interface > > > segment_vector
void extend(const double amount)
#define WBAssert(condition, message)
std::string get_full_json_path(size_t max_size=std::numeric_limits< size_t >::max()) const
void get_coordinates(const std::string &name, Parameters &prm, const CoordinateSystem coordinate_system)
std::vector< std::shared_ptr< Features::SubductingPlateModels::Velocity::Interface > > default_velocity_models
BoundingBox< 2 > surface_bounding_box
double cos(const double angle)
double distance_from_plane
static void declare_entries(Parameters &prm, const std::string &parent_name, const std::vector< std::string > &required_entries)
double distance_along_plane
void properties(const Point< 3 > &position_in_cartesian_coordinates, const Objects::NaturalCoordinate &position_in_natural_coordinates, const double depth, const std::vector< std::array< unsigned int, 3 >> &properties, const double gravity, const std::vector< size_t > &entry_in_output, std::vector< double > &output) const override final
PointDistanceFromCurvedPlanes distance_point_from_curved_planes(const Point< 3 > &check_point, const Objects::NaturalCoordinate &natural_coordinate, const Point< 2 > &reference_point, const std::vector< Point< 2 > > &point_list, const std::vector< std::vector< double > > &plane_segment_lengths, const std::vector< std::vector< Point< 2 > > > &plane_segment_angles, const double start_radius, const std::unique_ptr< CoordinateSystems::Interface > &coordinate_system, const bool only_positive, const Objects::BezierCurve &bezier_curve)
std::vector< Objects::Segment< Features::SubductingPlateModels::Temperature::Interface, Features::SubductingPlateModels::Composition::Interface, Features::SubductingPlateModels::Grains::Interface, Features::SubductingPlateModels::Velocity::Interface > > default_segment_vector
std::vector< std::string > feature_tags
WorldBuilder::World * world
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
#define WBAssertThrow(condition, message)
bool get_unique_pointers(const std::string &name, std::vector< std::unique_ptr< T > > &vector)
std::unique_ptr< WorldBuilder::CoordinateSystems::Interface > coordinate_system
std::vector< std::vector< Point< 2 > > > slab_segment_thickness
std::vector< std::vector< double > > slab_segment_lengths
static void declare_entries(Parameters &prm, const std::string &parent_name, const std::vector< std::string > &required_entries)
const BoundingBox< 2 > & get_surface_bounding_box() const
static void declare_entries(Parameters &prm, const std::string &parent_name="", const std::vector< std::string > &required_entries={})
double fraction_of_segment
std::size_t original_number_of_coordinates
std::vector< std::array< std::array< double, 3 >, 3 > > rotation_matrices
void declare_entry(const std::string &name, const Types::Interface &type, const std::string &documentation)
~SubductingPlate() override final
std::vector< T > get_vector(const std::string &name)
std::vector< double > total_slab_length
std::vector< std::shared_ptr< Features::SubductingPlateModels::Temperature::Interface > > default_temperature_models
T get(const std::string &name)
rapidjson::Document declarations
void unroll_into(std::vector< double > &vector, const size_t start_entry=0) const
double buffer_around_slab_cartesian
std::vector< Point< 2 > > coordinates
double maximum_slab_thickness
bool point_inside(const Point< spacedim > &p, const double tolerance=std::numeric_limits< double >::epsilon()) const
static void declare_entries(Parameters &prm, const std::string &parent_name, const std::vector< std::string > &required_entries)