diff --git a/CHANGELOG.md b/CHANGELOG.md index 3919a5fd1..c426e75e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Introduces a bounding box for searching the fault and the subducting plate model properties (temperature, composition, grains) in the lateral direction. This reduces the computation time by constraining the number of points for which the expensive distance_point_from_curved_planes function is called. \[Arushi Saxena; 2021-07-15; [#219](https://github.com/GeodynamicWorldBuilder/WorldBuilder/issues/219)\] - Chaning the internal interface of the get function to add a new structure (AdditionalParameters) to hold additional parameters (total_local_segment_length and local_thickness). The local_thickness has been moved away from the PointDistanceFromCurvedPlanes structure. \[Menno Fraters; 2021-09-08; [#330](github.com/GeodynamicWorldBuilder/WorldBuilder/pull/282)\] - Changed the name of the main branch from master to main \[Menno Fraters; 2021-10-28; [#350](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/350)\] +- Ridge coordinates are now an array of ridges, allowing mulitple ridges within a single oceanic plate with transform faults in between. \[Menno Fraters; 2021-11-03; [#362](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/362)\] ### Fixed - Using slabs and faults beyond the -180 to 180 range gave issues. These are now fixed and it now works and is tested for the -380 to 380 range. \[Menno Fraters; 2021-10-22; [#338](https://github.com/GeodynamicWorldBuilder/WorldBuilder/issues/338), [#340](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/340) and [#342](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/342)\] diff --git a/cookbooks/2d_cartesian_subduction_rift/2d_cartesian_subduction_rift.wb b/cookbooks/2d_cartesian_subduction_rift/2d_cartesian_subduction_rift.wb index 1e283ca71..b73f2a2a8 100644 --- a/cookbooks/2d_cartesian_subduction_rift/2d_cartesian_subduction_rift.wb +++ b/cookbooks/2d_cartesian_subduction_rift/2d_cartesian_subduction_rift.wb @@ -4,7 +4,7 @@ "features": [ {"model":"oceanic plate", "name":"oceanic plate", "coordinates":[[-1e3,-1e3],[1150e3,-1e3],[1150e3,1e3],[-1e3,1e3]], - "temperature models":[{"model":"plate model", "max depth":95e3, "bottom temperature":1600, "spreading velocity":0.005, "ridge coordinates":[[100e3,-1e3],[100e3,1e3]]}], + "temperature models":[{"model":"plate model", "max depth":95e3, "bottom temperature":1600, "spreading velocity":0.005, "ridge coordinates":[[[100e3,-1e3],[100e3,1e3]]]}], "composition models":[{"model":"uniform", "compositions":[0], "max depth":10e3}, {"model":"uniform", "compositions":[1], "min depth":10e3, "max depth":95e3}]}, diff --git a/cookbooks/2d_cartesian_subduction_rift_adiabatic/2d_cartesian_subduction_rift_adiabatic.wb b/cookbooks/2d_cartesian_subduction_rift_adiabatic/2d_cartesian_subduction_rift_adiabatic.wb index dc5af8fd7..dacb16076 100644 --- a/cookbooks/2d_cartesian_subduction_rift_adiabatic/2d_cartesian_subduction_rift_adiabatic.wb +++ b/cookbooks/2d_cartesian_subduction_rift_adiabatic/2d_cartesian_subduction_rift_adiabatic.wb @@ -4,7 +4,7 @@ "features": [ {"model":"oceanic plate", "name":"oceanic plate", "coordinates":[[-1e3,-1e3],[1150e3,-1e3],[1150e3,1e3],[-1e3,1e3]], - "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[100e3,-1e3],[100e3,1e3]]}], + "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[[100e3,-1e3],[100e3,1e3]]]}], "composition models":[{"model":"uniform", "compositions":[0], "max depth":10e3}, {"model":"uniform", "compositions":[1], "min depth":10e3, "max depth":95e3}]}, diff --git a/cookbooks/2d_cartesian_subduction_rift_sepran_example/2d_cartesian_subduction_rift_sepran_example.wb b/cookbooks/2d_cartesian_subduction_rift_sepran_example/2d_cartesian_subduction_rift_sepran_example.wb index a2ce0af4f..50f303fa3 100644 --- a/cookbooks/2d_cartesian_subduction_rift_sepran_example/2d_cartesian_subduction_rift_sepran_example.wb +++ b/cookbooks/2d_cartesian_subduction_rift_sepran_example/2d_cartesian_subduction_rift_sepran_example.wb @@ -12,7 +12,7 @@ { "model":"plate model", "max depth":95e3, "bottom temperature":1600, "spreading velocity":0.01, - "ridge coordinates":[[100e3,-1e3],[0e3,1e3]] + "ridge coordinates":[[[100e3,-1e3],[0e3,1e3]]] } ], "composition models": diff --git a/cookbooks/2d_spherical_subduction_rift/2d_spherical_subduction_rift.wb b/cookbooks/2d_spherical_subduction_rift/2d_spherical_subduction_rift.wb index 48c8762d5..252ea009e 100644 --- a/cookbooks/2d_spherical_subduction_rift/2d_spherical_subduction_rift.wb +++ b/cookbooks/2d_spherical_subduction_rift/2d_spherical_subduction_rift.wb @@ -5,7 +5,7 @@ "features": [ {"model":"oceanic plate", "name":"oceanic plate", "coordinates":[[-1,-1],[11.5,-1],[11.5,1],[-1,1]], - "temperature models":[{"model":"plate model", "max depth":95e3, "bottom temperature":1600, "spreading velocity":0.005, "ridge coordinates":[[1,-1],[1,1]]}], + "temperature models":[{"model":"plate model", "max depth":95e3, "bottom temperature":1600, "spreading velocity":0.005, "ridge coordinates":[[[1,-1],[1,1]]]}], "composition models":[{"model":"uniform", "compositions":[0], "max depth":10e3}, {"model":"uniform", "compositions":[1], "min depth":10e3, "max depth":95e3}]}, diff --git a/cookbooks/2d_spherical_subduction_rift_adiabatic/2d_spherical_subduction_rift_adiabatic.wb b/cookbooks/2d_spherical_subduction_rift_adiabatic/2d_spherical_subduction_rift_adiabatic.wb index 0a4fcc3e0..2672ea87d 100644 --- a/cookbooks/2d_spherical_subduction_rift_adiabatic/2d_spherical_subduction_rift_adiabatic.wb +++ b/cookbooks/2d_spherical_subduction_rift_adiabatic/2d_spherical_subduction_rift_adiabatic.wb @@ -5,7 +5,7 @@ "features": [ {"model":"oceanic plate", "name":"oceanic plate", "coordinates":[[-1,-1],[11.5,-1],[11.5,1],[-1,1]], - "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[1,-1],[1,1]]}], + "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[[1,-1],[1,1]]]}], "composition models":[{"model":"uniform", "compositions":[0], "max depth":10e3}, {"model":"uniform", "compositions":[1], "min depth":10e3, "max depth":95e3}]}, diff --git a/cookbooks/3d_cartesian_rift/3d_cartesian_rift.wb b/cookbooks/3d_cartesian_rift/3d_cartesian_rift.wb index 259e4a10f..fa9edcf7b 100644 --- a/cookbooks/3d_cartesian_rift/3d_cartesian_rift.wb +++ b/cookbooks/3d_cartesian_rift/3d_cartesian_rift.wb @@ -3,12 +3,12 @@ "features": [ {"model":"oceanic plate", "name":"oceanic plate A", "coordinates":[[-1e3,-1e3],[2001e3,-1e3],[2001e3,1000e3],[-1e3,1000e3]], - "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[1200e3,-1e3],[1200e3,1000e3]]}], + "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[[1200e3,-1e3],[1200e3,1000e3]]]}], "composition models":[{"model":"uniform", "compositions":[0], "max depth":10e3}, {"model":"uniform", "compositions":[1], "min depth":10e3, "max depth":95e3}]}, {"model":"oceanic plate", "name":"oceanic plate B", "coordinates":[[-1e3,1000e3],[2001e3,1000e3],[2001e3,2001e3],[-1e3,2001e3]], - "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[800e3,1000e3],[800e3,2000e3]]}], + "temperature models":[{"model":"plate model", "max depth":95e3, "spreading velocity":0.005, "ridge coordinates":[[[800e3,1000e3],[800e3,1500e3]],[[1000e3,1500e3],[1000e3,2000e3]]]}], "composition models":[{"model":"uniform", "compositions":[0], "max depth":10e3}, {"model":"uniform", "compositions":[1], "min depth":10e3, "max depth":95e3}]} diff --git a/include/world_builder/features/oceanic_plate_models/temperature/half_space_model.h b/include/world_builder/features/oceanic_plate_models/temperature/half_space_model.h index 015459364..c694ed1cc 100644 --- a/include/world_builder/features/oceanic_plate_models/temperature/half_space_model.h +++ b/include/world_builder/features/oceanic_plate_models/temperature/half_space_model.h @@ -86,7 +86,7 @@ namespace WorldBuilder double top_temperature; double bottom_temperature; double spreading_velocity; - std::vector > ridge_coordinates; + std::vector > > mid_oceanic_ridges; Utilities::Operations operation; }; diff --git a/include/world_builder/features/oceanic_plate_models/temperature/plate_model.h b/include/world_builder/features/oceanic_plate_models/temperature/plate_model.h index 11015f04e..57b225887 100644 --- a/include/world_builder/features/oceanic_plate_models/temperature/plate_model.h +++ b/include/world_builder/features/oceanic_plate_models/temperature/plate_model.h @@ -89,7 +89,7 @@ namespace WorldBuilder double top_temperature; double bottom_temperature; double spreading_velocity; - std::vector > ridge_coordinates; + std::vector > > mid_oceanic_ridges; Utilities::Operations operation; }; diff --git a/include/world_builder/features/subducting_plate_models/temperature/mass_conserving.h b/include/world_builder/features/subducting_plate_models/temperature/mass_conserving.h index 994bd9f31..2c7cdfedc 100644 --- a/include/world_builder/features/subducting_plate_models/temperature/mass_conserving.h +++ b/include/world_builder/features/subducting_plate_models/temperature/mass_conserving.h @@ -108,7 +108,7 @@ namespace WorldBuilder double surface_temperature; double taper_distance; bool adiabatic_heating; - std::vector> ridge_coordinates; + std::vector>> mid_oceanic_ridges; Utilities::Operations operation; }; diff --git a/source/features/oceanic_plate_models/temperature/half_space_model.cc b/source/features/oceanic_plate_models/temperature/half_space_model.cc index 85eb92692..d2f6d545d 100644 --- a/source/features/oceanic_plate_models/temperature/half_space_model.cc +++ b/source/features/oceanic_plate_models/temperature/half_space_model.cc @@ -82,9 +82,11 @@ namespace WorldBuilder "The spreading velocity of the plate in meter per year. " "This is the velocity with which one side moves away from the ridge."); - prm.declare_entry("ridge coordinates", Types::Array(Types::Point<2>(),2), - "A list of 2d points that defines the location of the ridge."); - + prm.declare_entry("ridge coordinates", Types::Array(Types::Array(Types::Point<2>(), 2),1), + "An list of ridges. Each ridge is a lists of at least 2 2d points which " + "define the location of the ridge. You need to define at least one ridge." + "So the an exmple with two ridges is " + "[[[10,20],[20,30],[10,40]],[[50,10],[60,10]]]."); } void @@ -97,13 +99,14 @@ namespace WorldBuilder top_temperature = prm.get("top temperature"); bottom_temperature = prm.get("bottom temperature"); spreading_velocity = prm.get("spreading velocity")/31557600; // m/seconds - ridge_coordinates = prm.get_vector >("ridge coordinates"); + mid_oceanic_ridges = prm.get_vector>>("ridge coordinates"); const double dtr = prm.coordinate_system->natural_coordinate_system() == spherical ? const_pi / 180.0 : 1.0; - for (auto &ridge_coordinate : ridge_coordinates) - { - ridge_coordinate *= dtr; - } + for (auto &ridge_coordinates : mid_oceanic_ridges) + for (auto &ridge_coordinate : ridge_coordinates) + { + ridge_coordinate *= dtr; + } } @@ -134,12 +137,47 @@ namespace WorldBuilder const CoordinateSystem coordinate_system = world->parameters.coordinate_system->natural_coordinate_system(); - for (unsigned int i_ridge = 0; i_ridge < ridge_coordinates.size()-1; i_ridge++) + + // first find if the coordinate is on this side of a ridge + unsigned int relevant_ridge = 0; + const Point<2> check_point(position_in_natural_coordinates.get_surface_coordinates(),position_in_natural_coordinates.get_coordinate_system()); + + // if there is only one ridge, there is no transform + if (mid_oceanic_ridges.size() > 1) + { + // There are more than one ridge, so there are transform faults + // Find the first which is on the same side + for (relevant_ridge = 0; relevant_ridge < mid_oceanic_ridges.size()-1; relevant_ridge++) + { + const Point<2> transform_point_0 = mid_oceanic_ridges[relevant_ridge+1][0]; + const Point<2> transform_point_1 = mid_oceanic_ridges[relevant_ridge][mid_oceanic_ridges[relevant_ridge].size()-1]; + const Point<2> reference_point = mid_oceanic_ridges[relevant_ridge][0]; + + const bool reference_on_side_of_line = (transform_point_1[0] - transform_point_0[0]) + * (reference_point[1] - transform_point_0[1]) + - (transform_point_1[1] - transform_point_0[1]) + * (reference_point[0] - transform_point_0[0]) + < 0; + const bool checkpoint_on_side_of_line = (transform_point_1[0] - transform_point_0[0]) + * (check_point[1] - transform_point_0[1]) + - (transform_point_1[1] - transform_point_0[1]) + * (check_point[0] - transform_point_0[0]) + < 0; + + + if (reference_on_side_of_line == checkpoint_on_side_of_line) + { + break; + } + + } + } + + for (unsigned int i_coordinate = 0; i_coordinate < mid_oceanic_ridges[relevant_ridge].size() - 1; i_coordinate++) { - const Point<2> segment_point0 = ridge_coordinates[i_ridge]; - const Point<2> segment_point1 = ridge_coordinates[i_ridge+1]; + const Point<2> segment_point0 = mid_oceanic_ridges[relevant_ridge][i_coordinate]; + const Point<2> segment_point1 = mid_oceanic_ridges[relevant_ridge][i_coordinate + 1]; - const Point<2> check_point(position_in_natural_coordinates.get_surface_coordinates(),position_in_natural_coordinates.get_coordinate_system()); // based on http://geomalgorithms.com/a02-_lines.html const Point<2> v = segment_point1 - segment_point0; const Point<2> w = check_point - segment_point0; diff --git a/source/features/oceanic_plate_models/temperature/plate_model.cc b/source/features/oceanic_plate_models/temperature/plate_model.cc index 76b77fbf0..118285ce1 100644 --- a/source/features/oceanic_plate_models/temperature/plate_model.cc +++ b/source/features/oceanic_plate_models/temperature/plate_model.cc @@ -78,8 +78,11 @@ namespace WorldBuilder "The spreading velocity of the plate in meter per year. " "This is the velocity with which one side moves away from the ridge."); - prm.declare_entry("ridge coordinates", Types::Array(Types::Point<2>(),2), - "A list of 2d points which define the location of the ridge."); + prm.declare_entry("ridge coordinates", Types::Array(Types::Array(Types::Point<2>(), 2),1), + "An list of ridges. Each ridge is a lists of at least 2 2d points which " + "define the location of the ridge. You need to define at least one ridge." + "So the an exmple with two ridges is " + "[[[10,20],[20,30],[10,40]],[[50,10],[60,10]]]."); } @@ -93,13 +96,14 @@ namespace WorldBuilder top_temperature = prm.get("top temperature"); bottom_temperature = prm.get("bottom temperature"); spreading_velocity = prm.get("spreading velocity")/31557600; - ridge_coordinates = prm.get_vector >("ridge coordinates"); + mid_oceanic_ridges = prm.get_vector>>("ridge coordinates"); const double dtr = prm.coordinate_system->natural_coordinate_system() == spherical ? const_pi / 180.0 : 1.0; - for (auto &ridge_coordinate : ridge_coordinates) - { - ridge_coordinate *= dtr; - } + for (auto &ridge_coordinates : mid_oceanic_ridges) + for (auto &ridge_coordinate : ridge_coordinates) + { + ridge_coordinate *= dtr; + } } @@ -127,16 +131,52 @@ namespace WorldBuilder } const int sommation_number = 100; + double distance_ridge = std::numeric_limits::max(); const CoordinateSystem coordinate_system = world->parameters.coordinate_system->natural_coordinate_system(); - for (unsigned int i_ridge = 0; i_ridge < ridge_coordinates.size()-1; i_ridge++) + + // first find if the coordinate is on this side of a ridge + unsigned int relevant_ridge = 0; + const Point<2> check_point(position_in_natural_coordinates.get_surface_coordinates(),position_in_natural_coordinates.get_coordinate_system()); + + // if there is only one ridge, there is no transform + if (mid_oceanic_ridges.size() > 1) + { + // There are more than one ridge, so there are transform faults + // Find the first which is on the same side + for (relevant_ridge = 0; relevant_ridge < mid_oceanic_ridges.size()-1; relevant_ridge++) + { + const Point<2> transform_point_0 = mid_oceanic_ridges[relevant_ridge+1][0]; + const Point<2> transform_point_1 = mid_oceanic_ridges[relevant_ridge][mid_oceanic_ridges[relevant_ridge].size()-1]; + const Point<2> reference_point = mid_oceanic_ridges[relevant_ridge][0]; + + const bool reference_on_side_of_line = (transform_point_1[0] - transform_point_0[0]) + * (reference_point[1] - transform_point_0[1]) + - (transform_point_1[1] - transform_point_0[1]) + * (reference_point[0] - transform_point_0[0]) + < 0; + const bool checkpoint_on_side_of_line = (transform_point_1[0] - transform_point_0[0]) + * (check_point[1] - transform_point_0[1]) + - (transform_point_1[1] - transform_point_0[1]) + * (check_point[0] - transform_point_0[0]) + < 0; + + + if (reference_on_side_of_line == checkpoint_on_side_of_line) + { + break; + } + + } + } + + for (unsigned int i_coordinate = 0; i_coordinate < mid_oceanic_ridges[relevant_ridge].size() - 1; i_coordinate++) { - const Point<2> segment_point0 = ridge_coordinates[i_ridge]; - const Point<2> segment_point1 = ridge_coordinates[i_ridge+1]; + const Point<2> segment_point0 = mid_oceanic_ridges[relevant_ridge][i_coordinate]; + const Point<2> segment_point1 = mid_oceanic_ridges[relevant_ridge][i_coordinate + 1]; - const Point<2> check_point(position_in_natural_coordinates.get_surface_coordinates(),position_in_natural_coordinates.get_coordinate_system()); // based on http://geomalgorithms.com/a02-_lines.html const Point<2> v = segment_point1 - segment_point0; const Point<2> w = check_point - segment_point0; diff --git a/source/features/subducting_plate_models/temperature/mass_conserving.cc b/source/features/subducting_plate_models/temperature/mass_conserving.cc index 3cee073d2..7bf4e77a5 100644 --- a/source/features/subducting_plate_models/temperature/mass_conserving.cc +++ b/source/features/subducting_plate_models/temperature/mass_conserving.cc @@ -129,8 +129,11 @@ namespace WorldBuilder prm.declare_entry("potential mantle temperature", Types::Double(-1), "The potential temperature of the mantle at the surface in Kelvin. If smaller than zero, the global value is used."); - prm.declare_entry("ridge coordinates", Types::Array(Types::Point<2>(), 2), - "A list of 2d points which define the location of the ridge."); + prm.declare_entry("ridge coordinates", Types::Array(Types::Array(Types::Point<2>(), 2),1), + "An list of ridges. Each ridge is a lists of at least 2 2d points which " + "define the location of the ridge. You need to define at least one ridge." + "So the an exmple with two ridges is " + "[[[10,20],[20,30],[10,40]],[[50,10],[60,10]]]."); } void @@ -172,12 +175,13 @@ namespace WorldBuilder surface_temperature = this->world->surface_temperature; - ridge_coordinates = prm.get_vector>("ridge coordinates"); + mid_oceanic_ridges = prm.get_vector>>("ridge coordinates"); const double dtr = prm.coordinate_system->natural_coordinate_system() == spherical ? const_pi / 180.0 : 1.0; - for (auto &ridge_coordinate : ridge_coordinates) - { - ridge_coordinate *= dtr; - } + for (auto &ridge_coordinates : mid_oceanic_ridges) + for (auto &ridge_coordinate : ridge_coordinates) + { + ridge_coordinate *= dtr; + } } double @@ -205,10 +209,46 @@ namespace WorldBuilder *(world->parameters.coordinate_system)); const Point<2> trench_point_2d(trench_point_natural.get_surface_coordinates(),trench_point_natural.get_coordinate_system()); // find the distance between the trench and ridge - for (unsigned int i_ridge = 0; i_ridge < ridge_coordinates.size() - 1; i_ridge++) + + + // first find if the coordinate is on this side of a ridge + unsigned int relevant_ridge = 0; + + + // if there is only one ridge, there is no transform + if (mid_oceanic_ridges.size() > 1) + { + // There are more than one ridge, so there are transform faults + // Find the first which is on the same side + for (relevant_ridge = 0; relevant_ridge < mid_oceanic_ridges.size()-1; relevant_ridge++) + { + const Point<2> transform_point_0 = mid_oceanic_ridges[relevant_ridge+1][0]; + const Point<2> transform_point_1 = mid_oceanic_ridges[relevant_ridge][mid_oceanic_ridges[relevant_ridge].size()-1]; + const Point<2> reference_point = mid_oceanic_ridges[relevant_ridge][0]; + + const bool reference_on_side_of_line = (transform_point_1[0] - transform_point_0[0]) + * (reference_point[1] - transform_point_0[1]) + - (transform_point_1[1] - transform_point_0[1]) + * (reference_point[0] - transform_point_0[0]) + < 0; + const bool checkpoint_on_side_of_line = (transform_point_1[0] - transform_point_0[0]) + * (trench_point_2d[1] - transform_point_0[1]) + - (transform_point_1[1] - transform_point_0[1]) + * (trench_point_2d[0] - transform_point_0[0]) + < 0; + + if (reference_on_side_of_line == checkpoint_on_side_of_line) + { + break; + } + + } + } + + for (unsigned int i_coordinate = 0; i_coordinate < mid_oceanic_ridges[relevant_ridge].size() - 1; i_coordinate++) { - const Point<2> segment_point0 = ridge_coordinates[i_ridge]; - const Point<2> segment_point1 = ridge_coordinates[i_ridge + 1]; + const Point<2> segment_point0 = mid_oceanic_ridges[relevant_ridge][i_coordinate]; + const Point<2> segment_point1 = mid_oceanic_ridges[relevant_ridge][i_coordinate + 1]; // based on http://geomalgorithms.com/a02-_lines.html const Point<2> v = segment_point1 - segment_point0; diff --git a/source/parameters.cc b/source/parameters.cc index 6525cbe93..311754e45 100644 --- a/source/parameters.cc +++ b/source/parameters.cc @@ -541,6 +541,54 @@ namespace WorldBuilder } + template<> + std::vector > > + Parameters::get_vector(const std::string &name) + { + std::vector > > vector; + const std::string strict_base = this->get_full_json_path(); + if (Pointer((strict_base + "/" + name).c_str()).Get(parameters) != nullptr) + { + Value *array1 = Pointer((strict_base + "/" + name).c_str()).Get(parameters); + + for (size_t i = 0; i < array1->Size(); ++i ) + { + const std::string base = (strict_base + "/").append(name).append("/").append(std::to_string(i)); + Value *array2 = Pointer((base).c_str()).Get(parameters); + + // Not sure why cppcheck it is generating the warning + // Filed a question at: https://sourceforge.net/p/cppcheck/discussion/general/thread/429759f85e/ + // cppcheck-suppress constStatement + std::vector > sub_vector(array2->Size(),Point<2>(NaN::DSNAN,NaN::DSNAN,coordinate_system->natural_coordinate_system())); + for (size_t j = 0; j < array2->Size(); ++j ) + { + const std::string base_extended = base + "/" + std::to_string(j); + + WBAssertThrow(Pointer((base_extended).c_str()).Get(parameters)->Size() == 2, + "Array " << i << " is supposed to be a 2d point, but the inner array dimensions of " + << j << " is " << Pointer((base_extended).c_str()).Get(parameters)->Size() << "."); + double value1; + double value2; + + try + { + value1 = Pointer((base_extended + "/0").c_str()).Get(parameters)->GetDouble(); + value2 = Pointer((base_extended + "/1").c_str()).Get(parameters)->GetDouble(); + } + catch (...) + { + WBAssertThrow(false, "Could not convert values of " << base << " into doubles, because it could not covert the sub-elements into doubles."); + } + sub_vector[j][0] = value1; + sub_vector[j][1] = value2; + } + vector.push_back(sub_vector); + } + } + return vector; + } + + template<> std::vector":[[[0,1],[2,3]],[[4,5],[6,7],[8,9]]], +"vector of vectors of points<2> nan":[[[0,1],[2,3]],[[4,5],[6,7],["not a number",9]]], "subsection 1": { "unsigned int":5, diff --git a/tests/unit_tests/unit_test_world_builder.cc b/tests/unit_tests/unit_test_world_builder.cc index 574449676..83f07ead4 100644 --- a/tests/unit_tests/unit_test_world_builder.cc +++ b/tests/unit_tests/unit_test_world_builder.cc @@ -23,6 +23,7 @@ #include "world_builder/config.h" #include "world_builder/coordinate_system.h" +#include "world_builder/coordinate_systems/cartesian.h" #include "world_builder/coordinate_systems/interface.h" #include "world_builder/features/continental_plate.h" #include "world_builder/features/interface.h" @@ -3828,6 +3829,8 @@ TEST_CASE("WorldBuilder Parameters") Parameters prm(world); prm.initialize(file); + world.parameters.coordinate_system.swap(prm.coordinate_system); + CHECK_THROWS_WITH(prm.get("non existent unsigned int"), Contains("internal error: could not retrieve the default value at")); @@ -3993,6 +3996,27 @@ TEST_CASE("WorldBuilder Parameters") CHECK(v_3x3_array[1][2][1] == Approx(16.0)); CHECK(v_3x3_array[1][2][2] == Approx(17.0)); + std::vector > > v_v_p2 = prm.get_vector>>("vector of vectors of points<2>"); + CHECK(v_v_p2.size() == 2); + CHECK(v_v_p2[0].size() == 2); + CHECK(v_v_p2[0][0][0] == Approx(0.0)); + CHECK(v_v_p2[0][0][1] == Approx(1.0)); + CHECK(v_v_p2[0][1][0] == Approx(2.0)); + CHECK(v_v_p2[0][1][1] == Approx(3.0)); + + CHECK(v_v_p2[1].size() == 3); + CHECK(v_v_p2[1][0][0] == Approx(4.0)); + CHECK(v_v_p2[1][0][1] == Approx(5.0)); + CHECK(v_v_p2[1][1][0] == Approx(6.0)); + CHECK(v_v_p2[1][1][1] == Approx(7.0)); + CHECK(v_v_p2[1][2][0] == Approx(8.0)); + CHECK(v_v_p2[1][2][1] == Approx(9.0)); + + + CHECK_THROWS_WITH(prm.get_vector>>("vector of vectors of points<2> nan"), + Contains("Could not convert values of /vector of vectors of points<2> nan/1 into doubles")); + + /*CHECK_THROWS_WITH(prm.get_vector("non existent string vector"), Contains("internal error: could not retrieve the default value at"));