Issue 1871 - Adds UTM coordinate resolution; including topography.#1937
Issue 1871 - Adds UTM coordinate resolution; including topography.#1937lsawade wants to merge 6 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends SPECFEM++’s 3D I/O and assembly pipeline to support geographic (lat/lon/depth) source/receiver inputs for UTM-projected meshes, and to automatically resolve depth-based coordinates against surface topography.
Changes:
- Add geographic coordinate parsing for YAML/CMTSOLUTION/FORCESOLUTION sources and for STATIONS receivers (with UTM projection deferred to assembly time).
- Introduce a
surface_elevation_at()algorithm and use it inresolve_coordinates()to resolve depth-based coordinates against the mesh free-surface. - Plumb UTM projection config + free-surface face data through the assembled mesh; add unit tests + test data.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit-tests/serial.cmake | Adds surface_elevation_tests target and registers it for serial discovery. |
| tests/unit-tests/io/sources/test_source_solutions.hpp | Adds expected-source declarations for geographic YAML/CMT cases. |
| tests/unit-tests/io/sources/test_source_solutions.cpp | Adds expected-source instances using geographic_coordinates. |
| tests/unit-tests/io/sources/test_read_sources_yaml.cpp | Adds YAML-node test coverage for geographic moment-tensor input. |
| tests/unit-tests/io/sources/test_read_sources_file.cpp | Adds CMTSOLUTION file-based test case for geographic moment tensor. |
| tests/unit-tests/io/sources/data/dim3/single_moment_tensor_geographic.CMTSOLUTION | New CMTSOLUTION fixture with lat/lon/depth fields. |
| tests/unit-tests/io/receivers/test_read_stations_file.cpp | Adds a geographic STATIONS parsing test. |
| tests/unit-tests/io/receivers/data/dim3/single_station_geographic_3d.txt | New STATIONS fixture with lat/lon + burial(depth). |
| tests/unit-tests/algorithms/dim3/surface_elevation_test.cpp | New unit tests covering surface elevation interpolation + topo depth resolution. |
| core/specfem/source/dim3/source.tpp | Adds geographic YAML coordinate ingestion for 3D sources. |
| core/specfem/program/dim3/program.cpp | Passes geographic flag to receiver reading based on UTM mesh config. |
| core/specfem/io/sources/impl/solution_format_helpers.hpp | Adds get_double() helper for higher-precision field parsing. |
| core/specfem/io/sources/impl/dim3/forcesolution.cpp | Adds geographic coordinate support + double-precision parsing for FORCESOLUTION. |
| core/specfem/io/sources/impl/dim3/cmtsolution.cpp | Adds geographic coordinate support + double-precision parsing for CMTSOLUTION. |
| core/specfem/io/receivers/dim3/read_receivers.cpp | Adds geographic mode to interpret STATIONS/YAML receiver coordinates as lat/lon/depth. |
| core/specfem/io.hpp | Documents/extends 3D receiver APIs with geographic flag. |
| core/specfem/assembly/sources.cpp | Passes optional UTM projection config into source location for geographic inputs. |
| core/specfem/assembly/resolve_coordinates.cpp | Uses surface_elevation_at() to resolve depth-based cartesian coords against topography. |
| core/specfem/assembly/receivers/dim3/receivers.cpp | Resolves receiver generic coordinates using optional UTM config. |
| core/specfem/assembly/mesh/dim3/mesh.hpp | Adds UTM projection fields + stores top free-surface faces on assembled mesh. |
| core/specfem/assembly/assembly/dim3/assembly.cpp | Copies UTM config + free-surface faces from raw mesh into assembled mesh. |
| core/specfem/algorithms/locate_point/dim3/surface_elevation.cpp | Implements free-surface elevation query (with MPI reduction). |
| core/specfem/algorithms/locate_point.hpp | Declares surface_elevation_at() API. |
| core/specfem/algorithms/CMakeLists.txt | Links algorithms library against specfem::mpi (needed by new algorithm). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (Node["latitude"] && Node["longitude"]) { | ||
| const double lon = Node["longitude"].as<double>(); | ||
| const double lat = Node["latitude"].as<double>(); | ||
| const double depth = Node["depth"].as<double>(); | ||
| this->read_coordinates_ = | ||
| std::make_unique<specfem::coordinate_systems::geographic_coordinates>( | ||
| lon, lat, depth); | ||
| } else { | ||
| this->global_coordinates = { Node["x"].as<type_real>(), | ||
| Node["y"].as<type_real>(), | ||
| Node["z"].as<type_real>() }; | ||
| } |
|
@int-ptr-ptr, added you since this is relevant for understanding if you have true topography in your setup. (Not relevant for flat acoustic layer) |
| // The face fixes one reference coordinate; we Newton-solve the other two so | ||
| // the interpolated (x, y) matches the target (z is ignored), then read z. | ||
| if (sel_face >= 0) { | ||
| const int compute_ispec = |
There was a problem hiding this comment.
Is this just interpolate1d/2d?
There was a problem hiding this comment.
The problem here is that z is unknown
| #include <tuple> | ||
| #include <utility> | ||
|
|
||
| std::pair<type_real, type_real> specfem::algorithms::surface_elevation_at( |
There was a problem hiding this comment.
This likely needs a restructure for maintainance. We should talk.
| quadratures }; | ||
|
|
||
| // Needed to project geographic source/receiver coordinates. | ||
| this->mesh.utm_projection_zone = mesh.utm_projection_zone; |
There was a problem hiding this comment.
Should this like in assembly::mesh or mesh::mesh? We need to discuss.
| @@ -0,0 +1,169 @@ | |||
| #include "specfem/algorithms/locate_point.hpp" | |||
|
|
|||
| #include "specfem/assembly/mesh.hpp" | |||
There was a problem hiding this comment.
@int-ptr-ptr can you have a look at this. We are not sure what the interface here should be. project_point_on_surface?
This also assumes that the topography has 0 cliffs. Maybe you have an idea?
Description
Issue Number
Closes #1871
Checklist
Please make sure to check developer documentation on specfem docs.