Skip to content

Add topograhpy infrastructure#848

Merged
MFraters merged 32 commits intoGeodynamicWorldBuilder:mainfrom
MFraters:add_topograhpy_infrastructure
Feb 21, 2026
Merged

Add topograhpy infrastructure#848
MFraters merged 32 commits intoGeodynamicWorldBuilder:mainfrom
MFraters:add_topograhpy_infrastructure

Conversation

@MFraters
Copy link
Member

An alternative implementation to #814 for the topography interface (issue #780). The difference is that this implementation can have different topography models per feature. It is still very much a work in progress, since not all features and geometries are implemented, but is as already workable, as can be seen in the example below. @Djneu would this also work for your use-cases? @alanjyu where you also interested in this, and if so, does this work for you as well?

I am thining of turning the topography input from a single value into a surface, like the min and max depht. That would allow to seamlessly use Litho1.0 data. (as a side-note, I probably want to rework the current implementation of surfaces to be more flexible and in line with the rest, but that is for a different pull request.)

screenshot_topography

This is made with the following world builder file:

{
  "version":"1.1",
  "coordinate system":{"model":"spherical", "depth method":"begin at end segment"},
    "surface temperature":293.15,
  "force surface temperature":true,
  "features":
  [
    {"model":"continental plate", "name":"Continent plate A", "coordinates":[[-1,10],[41,10],[41,15],[-1,15]], "min depth":-1e2,
     "topography models":[{"model":"uniform","topography":50000}],
     "temperature models":[{"model":"uniform", "min depth":-1e2, "max depth":95e3, "temperature":500}],
     "composition models":[{"model":"uniform", "compositions":[0], "min depth":-1e2}]},

    {"model":"continental plate", "name":"Continent plate B", "coordinates":[[20,12],[31,12],[31,15],[20,15]], "min depth":-1e2,
     "topography models":[{"model":"uniform","topography":70000}],
     "temperature models":[{"model":"uniform", "min depth":-1e2, "max depth":95e3, "temperature":500}],
     "composition models":[{"model":"uniform", "compositions":[1], "min depth":-1e2}]},

    {"model":"continental plate", "name":"Continent plate C", "coordinates":[[10,12],[20,12],[20,15],[10,15]], "min depth":-1e2,
     "topography models":[{"model":"uniform","topography":-10000}],
     "temperature models":[{"model":"uniform", "min depth":-1e2, "max depth":95e3, "temperature":500}],
     "composition models":[{"model":"uniform", "compositions":[2], "min depth":-1e2}]},

      // no topography and everywhere in the continent. Should not change any topography
    {"model":"continental plate", "name":"Continent plate D", "coordinates":[[-1,10],[41,10],[41,15],[-1,15]], "min depth":-1e2,
     "composition models":[{"model":"uniform", "compositions":[3], "min depth":-1e2, "max depth":25e3}]},

    {"model":"oceanic plate", "name":"oceanic plate A", "coordinates":[[-1,0],[41,0],[41,10],[-1,10]], "min depth":-1e2,
     "temperature models":[{"model":"half space model", "max depth":95e3, "min depth":-1e2, "spreading velocity":0.005, "ridge coordinates":[[[10,0], [10,5]],[[20,5],[20,10]]]}],
     "composition models":[{"model":"uniform", "compositions":[4], "min depth":-1e2}]},

    {"model":"oceanic plate", "name":"oceanic plate B", "coordinates":[[12.5,2.5],[17.5,2.5],[17.5,5],[12.5,5]], "min depth":-1e2,
     "topography models":[{"model":"uniform", "topography":10000}],
     "composition models":[{"model":"uniform", "compositions":[5], "min depth":-1e2}]}
  ]
}

@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch 2 times, most recently from 0794ad8 to bf6d7a5 Compare August 24, 2025 09:47
@Djneu
Copy link
Contributor

Djneu commented Aug 25, 2025

Sorry I didn't get a chance to look at the older pull request, I ended up getting sick last week! I think this sounds like a good way to do this, I think in the initial pull request we were just focused on getting a simple interface implemented so it was quite basic.

One of the main points of discussion if I recall was defining a surface type so that we could tell ASPECT whether it is adding topography by either thickening at the top, or in the case of isostasy, thickening at the bottom so that the entire lithosphere is uplifted. I didn't look through all the code, but was this in here somewhere?

@MFraters
Copy link
Member Author

Sorry I didn't get a chance to look at the older pull request, I ended up getting sick last week!
Oh, I am sorry to hear that. I hope you feel better now.

One of the main points of discussion if I recall was defining a surface type so that we could tell ASPECT whether it is adding topography by either thickening at the top, or in the case of isostasy, thickening at the bottom so that the entire lithosphere is uplifted. I didn't look through all the code, but was this in here somewhere?

hmm, I may need to think a bit more about this, but what the world builder currently does is that is just works from depth 0, which is independent of the topography. With that, in gwb-grid I can compute the a depth from the surface and a depth from a reference, that happens here (notice the last two line):

grid_x[counter] = x_min + (static_cast<double>(i) - 1.0) * dlong;
const double longitude = grid_x[i];
domain_height [counter]= outer_radius - inner_radius;
cell_height[counter] = domain_height[counter] / static_cast<double>(n_cell_z);
grid_z[counter] = inner_radius + (static_cast<double>(j) - 1.0) * cell_height[counter];
grid_depth_wrt_surface[counter] = domain_height[counter] - (static_cast<double>(j) - 1.0) * cell_height[counter];
const double radius = grid_z[counter];
const double x = radius * std::cos(longitude);
const double z = radius * std::sin(longitude);
std::vector<std::array<unsigned ,3>> properties;
properties.push_back({{6,0,0}}); // topography
const std::array<double,2> coords = {{x,z}};
const double topography = world->properties(coords, grid_depth_wrt_surface[counter],properties)[0];
grid_x[counter] = x_min + (static_cast<double>(i) - 1.0) * dlong;
domain_height [counter]= outer_radius + topography - inner_radius;
cell_height[counter] = domain_height[counter] / static_cast<double>(n_cell_z);
grid_z[counter] = inner_radius + (static_cast<double>(j) - 1.0) * cell_height[counter];
grid_depth_wrt_surface[counter] = domain_height[counter] - (static_cast<double>(j) - 1.0) * cell_height[counter];
grid_depth_wrt_reference[counter] = domain_height[counter] - (static_cast<double>(j) - 1.0) * cell_height[counter] - topography;
counter++;

And later I pass in the depth with respect to the surface:

std::vector<double> output = world->properties(coords, grid_depth_wrt_surface[i],properties);

So how it is currently setup, the caller (gwb-grid or aspect) is responsible to put in the correct depth. This means that we could make a switch in aspect which depth to put into the world builder. But this would probably require to know the topography in aspect. I don't know whether this is desirable or feasible in aspect since it has been a while since I have looked at the topography and world builder code in aspect. Do you think this would work or not?

@Djneu
Copy link
Contributor

Djneu commented Sep 8, 2025

I think this sounds good for now, and we can update it later if it is necessary when isostasy is implemented. From the third point on option 2 in #780, I think the idea was that we pass the topography separately and then ASPECT will decide how to apply the topography, but this was something that we still need to implement within ASPECT for it to work.

@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from 4a5fa5d to 6caf2a9 Compare February 17, 2026 10:15
@MFraters MFraters mentioned this pull request Feb 17, 2026
12 tasks
@MFraters
Copy link
Member Author

It turns out that the std::cos and std::sin are different enough to generate significant differences between linux, macos and windows. I have replaced these function in gwb-grid with the FT versions of these functions which I had implemented a while ago, and now they all yield the same result.

@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from aec3069 to 980fe53 Compare February 19, 2026 18:43
@coveralls
Copy link

coveralls commented Feb 19, 2026

Pull Request Test Coverage Report for Build 22260437828

Details

  • 483 of 489 (98.77%) changed or added relevant lines in 16 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+0.06%) to 98.457%

Changes Missing Coverage Covered Lines Changed/Added Lines %
source/world_builder/utilities.cc 15 16 93.75%
source/world_builder/world.cc 11 13 84.62%
source/gwb-grid/main.cc 139 142 97.89%
Files with Coverage Reduction New Missed Lines %
source/world_builder/features/plume.cc 1 98.31%
Totals Coverage Status
Change from base Build 22201283453: 0.06%
Covered Lines: 9254
Relevant Lines: 9399

💛 - Coveralls

@MFraters MFraters changed the title [WIP] Add topograhpy infrastructure Add topograhpy infrastructure Feb 19, 2026
@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch 2 times, most recently from 2a35f69 to b2411b1 Compare February 19, 2026 21:17
@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from b2411b1 to eb2ba0b Compare February 19, 2026 21:43
@github-actions
Copy link

github-actions bot commented Feb 19, 2026

Benchmark Main Feature Difference (99.9% CI)
Slab interpolation simple none 1.125 ± 0.005 (s=374) 1.289 ± 0.007 (s=374) +14.4% .. +14.7%
Slab interpolation curved simple none 1.022 ± 0.006 (s=406) 1.169 ± 0.006 (s=417) +14.2% .. +14.5%
Spherical slab interpolation simple none 1.016 ± 0.008 (s=435) 1.145 ± 0.007 (s=402) +12.6% .. +12.9%
Slab interpolation simple curved CMS 1.061 ± 0.005 (s=421) 1.208 ± 0.006 (s=378) +13.7% .. +13.9%
Spherical slab interpolation simple CMS 1.454 ± 0.009 (s=302) 1.611 ± 0.009 (s=289) +10.7% .. +11.0%
Spherical fault interpolation simple none 1.118 ± 0.008 (s=392) 1.270 ± 0.008 (s=366) +13.4% .. +13.8%
Cartesian min max surface 2.500 ± 0.015 (s=165) 3.083 ± 0.014 (s=160) +23.1% .. +23.5%
Spherical min max surface 7.187 ± 0.058 (s=60) 8.678 ± 0.107 (s=56) +20.0% .. +21.5%

@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from eb2ba0b to b0a36eb Compare February 19, 2026 22:14
@MFraters
Copy link
Member Author

I think this looks ready to me. I will look over it again tomorrow and if everything still looks good, merge it and continue with the release of version 1.1.

The increase in run time for the benchmarks is most likely due to the addition of topography in gwb-grid. So it should not affect any other code using the world builder if topography is not used.

@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from b0a36eb to 74ae6ad Compare February 20, 2026 14:17
@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from 74ae6ad to bb77a44 Compare February 20, 2026 14:55
@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from bb77a44 to b15adad Compare February 20, 2026 16:15
@MFraters MFraters force-pushed the add_topograhpy_infrastructure branch from 537c28a to 6edfcd1 Compare February 21, 2026 16:44
@MFraters MFraters merged commit 67e6272 into GeodynamicWorldBuilder:main Feb 21, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants