diff --git a/CHANGELOG.md b/CHANGELOG.md index c426e75e5..1ed2b395f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - The option for a smooth slab temperature structure that conserves mass with distance along the slab surface. \[Magali Billen; 2021-07-28; [#323](github.com/GeodynamicWorldBuilder/WorldBuilder/pull/323)\] - The option for a temperature model for an oceanic plate with a constant age using the plate model. \[Haoyuan Li; 2021-10-29; [#344](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/344)\] - The cmake targets to easily switch between debug and release mode \[Menno Fraters; 2021-10-31; [#361](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/361)\] +- A new depth method for the spherical coordinate system called begin at end segment. This adds the spherical correction to the end of the segment instead of the beginning, resulting in a smoother transition between segments. \[Menno Fraters; 2021-11-06; [#364](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/364), [#365](https://github.com/GeodynamicWorldBuilder/WorldBuilder/pull/365)\] ### Changed - The World Builder Visualizer will now use zlib compression for vtu files by default. If zlib is not available binary output will be used. \[Menno Fraters; 2021-06-26; [#282](github.com/GeodynamicWorldBuilder/WorldBuilder/pull/282)\] diff --git a/doc/manual/manual.tex b/doc/manual/manual.tex index b87420421..639d794c6 100644 --- a/doc/manual/manual.tex +++ b/doc/manual/manual.tex @@ -457,7 +457,17 @@ \subsection{Coordinate systems} Note that currently only the constant angle relative to the surface where it started (the left side of figure \ref{fig:coordinate_systems_line_spiral}). \end{remark} -The first option (line) is simpler, more intuitive and makes no assumptions about what a slab should do within the earth. The second option (spiral) is less intuitive, but implicitly includes gravity in the slab. There is a third option, which is a compromise between the first two. It uses the slab segments and recomputes the angle at the beginning of every segment. With small enough segments, this approximates the second option. We have implemented this option, because the implementation of the second option has proven to be difficult. So currently only the first and third option can be set through the \hl{depth method} parameter in the \hl{spherical} parameter, by setting the \hl{depth method} parameter to \hl{starting point} and \hl{begin point} respectively. Adding to the \WB{} file from the previous section by setting it to a spherical geometry, we get the following \WB{} file: +The first option (line) is simpler, more intuitive and makes no assumptions about what a slab should do within the earth. The second option (spiral) is less intuitive, +but implicitly includes gravity in the slab. There are two more options, option three and four, which are a compromise between the first two. +Both option three and four use the slab segments and recomputes the angle at the beginning of every segment. +The third option of these two actually applies it directly at the beginning of the segment. This is most logical, but it can lead to discontiuities between two curved slab segments, +even though they have the same ending and starting angle respectively. +The forth option applies the extra angle computed at the beginning of the segment to the end of the segment. This allows for a smmooth tranition and is generally recommended. +With small enough segments, both these approximates the second (spiral) option. We have implemented the other options because the implementation of the spiral option has proven to +be difficult and time consuming. +So currently only the first, third and fourth option can be set through the \hl{depth method} parameter in the \hl{spherical} parameter, by setting the \hl{depth method} parameter +to \hl{starting point}, \hl{begin point} and \hl{begin at end segment} respectively. +Adding to the \WB{} file from the previous section by setting it to a spherical geometry, we get the following \WB{} file: \begin{javascriptcode}{}{} { diff --git a/include/world_builder/coordinate_system.h b/include/world_builder/coordinate_system.h index 2bc930c22..f2f8b6ad3 100644 --- a/include/world_builder/coordinate_system.h +++ b/include/world_builder/coordinate_system.h @@ -58,6 +58,7 @@ namespace WorldBuilder { angle_at_starting_point_with_surface, angle_at_begin_segment_with_surface, + angle_at_begin_segment_applied_to_end_segment_with_surface, continuous_angle_with_surface, none }; diff --git a/source/coordinate_systems/spherical.cc b/source/coordinate_systems/spherical.cc index 83d4846f8..8d3be980f 100644 --- a/source/coordinate_systems/spherical.cc +++ b/source/coordinate_systems/spherical.cc @@ -44,8 +44,10 @@ namespace WorldBuilder prm.declare_entry("depth method", - Types::String("",std::vector({"starting point", "begin segment", "continuous"})), - R"(Which depth method to use in the spherical case. The available options are 'starting point' and 'begin segment'.)"); + Types::String("",std::vector({"starting point", "begin segment","begin at end segment", "continuous"})), + R"(Which depth method to use in the spherical case. The available options are 'starting point', )" + R"('begin segment' and 'begin at end segment'. See the manual section on coordinate systems for )" + R"(more info.)"); } @@ -60,11 +62,13 @@ namespace WorldBuilder used_depth_method = DepthMethod::angle_at_starting_point_with_surface; else if (string_depth_method == "begin segment") used_depth_method = DepthMethod::angle_at_begin_segment_with_surface; + else if (string_depth_method == "begin at end segment") + used_depth_method = DepthMethod::angle_at_begin_segment_applied_to_end_segment_with_surface; //else if (string_depth_method == "continuous") //used_depth_method = DepthMethod::continuous_angle_with_surface; else WBAssertThrow(true,"Option " << string_depth_method << " is not a valid depth method for spherical " - "coordinates. The available options are 'starting point' and 'begin segment'. " + "coordinates. The available options are 'starting point', 'begin segment' and 'begin at end segment'. " "The option 'continuous' is not yet available."); //std::cout << "string_depth_method = " << string_depth_method << std::endl; diff --git a/source/utilities.cc b/source/utilities.cc index 8bbd03aa6..d6cf68b3e 100644 --- a/source/utilities.cc +++ b/source/utilities.cc @@ -500,9 +500,10 @@ namespace WorldBuilder const DepthMethod depth_method = coordinate_system->depth_method(); WBAssertThrow(depth_method == DepthMethod::none || depth_method == DepthMethod::angle_at_starting_point_with_surface - || depth_method == DepthMethod::angle_at_begin_segment_with_surface, - "Only the depth methods none, angle_at_starting_point_with_surface and " - "angle_at_begin_segment_with_surface are implemented"); + || depth_method == DepthMethod::angle_at_begin_segment_with_surface + || depth_method == DepthMethod::angle_at_begin_segment_applied_to_end_segment_with_surface, + "Only the depth methods 'none', 'angle_at_starting_point_with_surface', 'angle_at_begin_segment_with_surface'" << + "and 'angle_at_begin_segment_applied_to_end_segment_with_surface' are implemented."); double min_distance_check_point_surface_2d_line = std::numeric_limits::infinity(); size_t i_section_min_distance = 0; @@ -892,6 +893,7 @@ namespace WorldBuilder double total_length = 0.0; double add_angle = 0.0; + double add_angle_correction = 0.0; double average_angle = 0.0; for (size_t i_segment = 0; i_segment < plane_segment_lengths[original_current_section].size(); i_segment++) { @@ -899,7 +901,11 @@ namespace WorldBuilder // compute the angle between the the previous begin and end if // the depth method is angle_at_begin_segment_with_surface. - if (i_segment != 0 && depth_method == DepthMethod::angle_at_begin_segment_with_surface) + if (i_segment != 0 + && + (depth_method == DepthMethod::angle_at_begin_segment_with_surface + || + depth_method == DepthMethod::angle_at_begin_segment_applied_to_end_segment_with_surface)) { const double add_angle_inner = (begin_segment * end_segment) / (begin_segment.norm() * end_segment.norm()); @@ -918,7 +924,8 @@ namespace WorldBuilder "this is probably caused by that begin and end segment are the same and round off error. " "The value of add_angle_inner = " << add_angle_inner); - add_angle += std::acos(add_angle_inner); + add_angle_correction = std::acos(add_angle_inner); + add_angle += add_angle_correction; WBAssert(!std::isnan(add_angle), "Internal error: The add_angle variable is not a number: " << add_angle @@ -957,7 +964,9 @@ namespace WorldBuilder const double interpolated_angle_top = plane_segment_angles[original_current_section][current_segment][0] + fraction_CPL_P1P2 * (plane_segment_angles[original_next_section][current_segment][0] - plane_segment_angles[original_current_section][current_segment][0]) - + add_angle; + + add_angle + + (depth_method == DepthMethod::angle_at_begin_segment_applied_to_end_segment_with_surface + && i_segment != 0 ? -add_angle_correction: 0); const double interpolated_angle_bottom = plane_segment_angles[original_current_section][current_segment][1] + fraction_CPL_P1P2 * (plane_segment_angles[original_next_section][current_segment][1] diff --git a/tests/app/depth_method_slab_begin_at_end_segment.dat b/tests/app/depth_method_slab_begin_at_end_segment.dat new file mode 100644 index 000000000..3a6bc2973 --- /dev/null +++ b/tests/app/depth_method_slab_begin_at_end_segment.dat @@ -0,0 +1,4 @@ +549100 1.62751e+6 0 549100 10 +5.5555e6 1.64208e+6 0 575225 10 +5.55037e+6 1.63356e+6 0 585225 10 +5.5555e6 1.64208e+6 0 595225 10 diff --git a/tests/app/depth_method_slab_begin_at_end_segment.wb b/tests/app/depth_method_slab_begin_at_end_segment.wb new file mode 100644 index 000000000..b11835b0a --- /dev/null +++ b/tests/app/depth_method_slab_begin_at_end_segment.wb @@ -0,0 +1,21 @@ +{ + "version":"0.5", + "coordinate system":{"model":"spherical","depth method":"begin at end segment"}, + "cross section":[[0,0],[45,0]],"surface temperature":273, "force surface temperature":true, + "potential mantle temperature":1673, "thermal expansion coefficient":3.1e-5, + "specific heat":1250, "thermal diffusivity":1.0e-6, + "features": + [ + { "model":"subducting plate", "name":"Slab", + "coordinates":[[25,-5],[25,5]], + "interpolation":"continuous monotone spline", + "dip point":[0,0], + "segments":[{"length":200e3,"thickness":[300e3], "top truncation":[-300e3], "angle":[0,30]}, + {"length":100e3, "thickness":[300e3], "top truncation":[-300e3], "angle":[30,50]}, + {"length":800e3, "thickness":[300e3], "top truncation":[-200e3], "angle":[50,50]}, + {"length":300e3, "thickness":[300e3], "top truncation":[-200e3], "angle":[50,10]}, + {"length":300e3, "thickness":[300e3], "top truncation":[-300e3], "angle":[10,50]}], + "temperature models":[{"model":"uniform", "min distance slab top":-200e3, "temperature":900}] + } + ] +} diff --git a/tests/app/depth_method_slab_begin_at_end_segment/screen-output.log b/tests/app/depth_method_slab_begin_at_end_segment/screen-output.log new file mode 100644 index 000000000..24855b735 --- /dev/null +++ b/tests/app/depth_method_slab_begin_at_end_segment/screen-output.log @@ -0,0 +1,5 @@ +# x y z d g T +549100 1.62751e+6 0 549100 10 1917.06 +5.5555e6 1.64208e+6 0 575225 10 900 +5.55037e+6 1.63356e+6 0 585225 10 900 +5.5555e6 1.64208e+6 0 595225 10 900