Skip to content

[SPH] Add MHD block to Phantom I/O#1889

Open
JackNarvaez wants to merge 7 commits into
Shamrock-code:mainfrom
JackNarvaez:phantom
Open

[SPH] Add MHD block to Phantom I/O#1889
JackNarvaez wants to merge 7 commits into
Shamrock-code:mainfrom
JackNarvaez:phantom

Conversation

@JackNarvaez

Copy link
Copy Markdown

Adds support for MHD fields (B/rho and psi/ch) in dump files.

Notes:

  • Magnetic fields are currently read from dump files containing (B/rho_x, B/rho_y, B/rho_z, psi/ch), not (Bx, By, Bz, psi). Support for the latter could be added in the future by multiplying with the density.
  • Shamrock can read both artificial viscosity and magnetic field data. However, since MHD currently only supports set_artif_viscosity_None(), dump files should not contain alpha.

@github-actions

Copy link
Copy Markdown
Contributor

Thanks @JackNarvaez for opening this PR!

You can do multiple things directly here:
1 - Comment pre-commit.ci run to run pre-commit checks.
2 - Comment pre-commit.ci autofix to apply fixes.
3 - Add label autofix.ci to fix authorship & pre-commit for every commit made.
4 - Add label light-ci to only trigger a reduced & faster version of the CI (need the full one before merge).
5 - Add label trigger-ci to create an empty commit to trigger the CI.

Once the workflow completes a message will appear displaying informations related to the run.

Also the PR gets automatically reviewed by gemini, you can:
1 - Comment /gemini review to trigger a review
2 - Comment /gemini summary for a summary
3 - Tag it using @gemini-code-assist either in the PR or in review comments on files

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces Magnetohydrodynamics (MHD) support to the SPH model, enabling the loading, processing, and writing of MHD fields (such as magnetic fields and psi/ch) from and to Phantom dump files. Key changes include adding MHD configuration helper functions, loading MHD fields during model initialization, and appending MHD data blocks when generating Phantom dumps. The review feedback highlights two main improvements: validating the sizes of the loaded MHD vector components to prevent potential out-of-bounds memory access, and removing an unnecessary empty third block (block_3rd) when writing the Phantom dump to avoid compatibility issues with external tools.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +1303 to +1305
for (u32 i = 0; i < Brhox.size(); i++) {
Brhoxyz.push_back({Brhox[i], Brhoy[i], Brhoz[i]});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Mismatched vector sizes can lead to out-of-bounds memory access and undefined behavior/crashes. We should validate that:

  1. The individual components of the magnetic field (Brhox, Brhoy, Brhoz) have the same size before constructing Brhoxyz.
  2. The constructed Brhoxyz and psich vectors have the same size as the coordinate vector xyz (if they are populated), ensuring that subsequent indexing using sel_index is safe.
        if (Brhox.size() != Brhoy.size() || Brhox.size() != Brhoz.size()) {
            shambase::throw_with_loc<std::runtime_error>(
                "MHD B/rho component vector sizes do not match");
        }

        for (u32 i = 0; i < Brhox.size(); i++) {
            Brhoxyz.push_back({Brhox[i], Brhoy[i], Brhoz[i]});
        }

        if (!Brhoxyz.empty() && Brhoxyz.size() != xyz.size()) {
            shambase::throw_with_loc<std::runtime_error>(
                "MHD B/rho vector size does not match particle count");
        }

        if (!psich.empty() && psich.size() != xyz.size()) {
            shambase::throw_with_loc<std::runtime_error>(
                "MHD psi/ch vector size does not match particle count");
        }

Comment on lines +1724 to +1726
PhantomDumpBlock block_3rd;
dump.blocks.push_back(std::move(block_3rd));
dump.blocks.push_back(std::move(block_mhd));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

An empty block_3rd is written to the Phantom dump file. Since ndust is 0, there is no dust data, and writing an empty block is unnecessary. Furthermore, init_from_phantom_dump searches for MHD fields by looping over all blocks, so the exact block index of block_mhd does not need to be padded. Writing an empty block may cause compatibility issues with other tools (like Phantom or Splash) that expect a specific block structure based on the header parameters.

Suggested change
PhantomDumpBlock block_3rd;
dump.blocks.push_back(std::move(block_3rd));
dump.blocks.push_back(std::move(block_mhd));
dump.blocks.push_back(std::move(block_mhd));

@y-lapeyre y-lapeyre changed the title Read and write MHD fields in dump files. [SPH] Add MHD block to Phantom I/O Jun 23, 2026
@tdavidcl

Copy link
Copy Markdown
Member

Hi @JackNarvaez thanks for the PR !
Would you have a very small reference phantom dump (~1MB) with MHD that we can use in the CI to test that load_from_dump + dump gives the same dump structure in the long run ?

@tdavidcl tdavidcl requested a review from y-lapeyre June 24, 2026 14:33
@JackNarvaez

Copy link
Copy Markdown
Author

mhdwave_00000.txt

Hi @tdavidcl
Sure! Here's a reduced Phantom dump file from the Isolated MHD wave test. It includes only the core variables: x, y, z, vx, vy, vz, u, B/rhox, B/rhoy, B/rhoz, psi/ch, h, and divB. I tested it, and Shamrock was able to read and write the MHD block in the dump files, producing results similar to those with Phantom, aside from the expected differences due to the AV scheme. Let me know if a Python script to run the test is also needed.

@y-lapeyre y-lapeyre left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thanks for the PR. Currently does not work on a simple load test

filename = "mhdwave_00000"

import shamrock
dump = shamrock.load_phantom_dump(filename)

dump.print_state()
libc++abi: terminating due to uncaught exception of type pybind11::error_already_set: RuntimeError: the byte count is not correct

I'll investigate now :)

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 69 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/shammodels/sph/src/Model.cpp 0.00% 63 Missing ⚠️
src/shammodels/sph/src/io/Phantom2Shamrock.cpp 0.00% 4 Missing ⚠️
...ls/sph/include/shammodels/sph/config/MHDConfig.hpp 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@y-lapeyre y-lapeyre self-requested a review July 6, 2026 10:22

@y-lapeyre y-lapeyre left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. @JackNarvaez Could you add a file named run_mhd_open_phnatom_dump.py in examples/sph

"""
Open a phantom dump
============================

This simple example shows how to open a phantom dump in shamrock,
including the MHD fields
"""

# %%
# Download a phantom dump
dump_folder = "_to_trash"
import os

os.system("mkdir -p " + dump_folder)

url = "https://raw.githubusercontent.com/Shamrock-code/reference-files/refs/heads/main/briowu_00000"

filename = dump_folder + "/briowu_00000"

from urllib.request import urlretrieve

urlretrieve(url, filename)

# %%
# Open the phantom dump

import shamrock

dump = shamrock.load_phantom_dump(filename)

# %%
# Print the data

dump.print_state()

@y-lapeyre y-lapeyre added in-review and removed draft labels Jul 6, 2026
@y-lapeyre y-lapeyre marked this pull request as ready for review July 6, 2026 10:25
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Workflow report

workflow report corresponding to commit c957664
Commiter email is yona.lapeyre@ens-lyon.fr

Light CI is enabled. This will only run the basic tests and not the full tests.
Merging a PR require the job "on PR / all" to pass which is disabled in this case.

Pre-commit check report

Pre-commit check: ✅

trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check for merge conflicts................................................Passed
check that executables have shebangs.....................................Passed
check that scripts with shebangs are executable..........................Passed
check for added large files..............................................Passed
check for case conflicts.................................................Passed
check for broken symlinks................................................Passed
check yaml...............................................................Passed
detect private key.......................................................Passed
No-tabs checker..........................................................Passed
Tabs remover.............................................................Passed
cmake-format.............................................................Passed
Validate GitHub Workflows................................................Passed
clang-format.............................................................Passed
ruff check...............................................................Passed
ruff format..............................................................Passed
Check doxygen headers....................................................Passed
Check license headers....................................................Passed
Check #pragma once.......................................................Passed
Check SYCL #include......................................................Passed
No ssh in git submodules remote..........................................Passed
No UTF-8 in files (except for authors)...................................Passed

Test pipeline can run.

Doxygen diff with main

Removed warnings : 8
New warnings : 9
Warnings count : 8006 → 8007 (0.0%)

Detailed changes :
- src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:59: warning: Member has_B_field() (function) of struct shammodels::sph::MHDConfig is not documented.
+ src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:59: warning: Member set_ideal_mhd_constrained_hyper_para(Tscal sigma_mhd, Tscal alpha_u) (function) of struct shammodels::sph::MHDConfig is not documented.
+ src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:63: warning: Member has_B_field() (function) of struct shammodels::sph::MHDConfig is not documented.
- src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:65: warning: Member has_psi_field() (function) of struct shammodels::sph::MHDConfig is not documented.
+ src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:69: warning: Member has_psi_field() (function) of struct shammodels::sph::MHDConfig is not documented.
- src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:71: warning: Member has_divB_field() (function) of struct shammodels::sph::MHDConfig is not documented.
+ src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:75: warning: Member has_divB_field() (function) of struct shammodels::sph::MHDConfig is not documented.
- src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:76: warning: Member has_curlB_field() (function) of struct shammodels::sph::MHDConfig is not documented.
+ src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:80: warning: Member has_curlB_field() (function) of struct shammodels::sph::MHDConfig is not documented.
- src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:81: warning: Member has_dtdivB_field() (function) of struct shammodels::sph::MHDConfig is not documented.
+ src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:85: warning: Member has_dtdivB_field() (function) of struct shammodels::sph::MHDConfig is not documented.
- src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:86: warning: Member print_status() (function) of struct shammodels::sph::MHDConfig is not documented.
+ src/shammodels/sph/include/shammodels/sph/config/MHDConfig.hpp:90: warning: Member print_status() (function) of struct shammodels::sph::MHDConfig is not documented.
- src/shammodels/sph/src/io/Phantom2Shamrock.cpp:198: warning: Member write_shamrock_units_in_phantom_dump< f64 >(std::optional< shamunits::UnitSystem< f64 > > &units, PhantomDump &dump, bool bypass_error) (function) of namespace shammodels::sph is not documented.
+ src/shammodels/sph/src/io/Phantom2Shamrock.cpp:213: warning: Member write_shamrock_units_in_phantom_dump< f64 >(std::optional< shamunits::UnitSystem< f64 > > &units, PhantomDump &dump, bool bypass_error) (function) of namespace shammodels::sph is not documented.
- src/shammodels/sph/src/io/Phantom2Shamrock.cpp:218: warning: Member write_shamrock_boundaries_in_phantom_dump(BCConfig< Tvec > &cfg, std::tuple< Tvec, Tvec > box_size, PhantomDump &dump, bool bypass_error) (function) of namespace shammodels::sph is not documented.
+ src/shammodels/sph/src/io/Phantom2Shamrock.cpp:233: warning: Member write_shamrock_boundaries_in_phantom_dump(BCConfig< Tvec > &cfg, std::tuple< Tvec, Tvec > box_size, PhantomDump &dump, bool bypass_error) (function) of namespace shammodels::sph is not documented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants