Skip to content

Symplectic integration in a user-defined magnetostatic vector potential#964

Open
cemitch99 wants to merge 72 commits into
BLAST-ImpactX:developmentfrom
cemitch99:add_user_nonlinear_element
Open

Symplectic integration in a user-defined magnetostatic vector potential#964
cemitch99 wants to merge 72 commits into
BLAST-ImpactX:developmentfrom
cemitch99:add_user_nonlinear_element

Conversation

@cemitch99

@cemitch99 cemitch99 commented May 15, 2025

Copy link
Copy Markdown
Member

This PR adds a new element that allows the user to track through a region with a specified magnetostatic vector potential. Symplectic integration is performed using the exact form of the nonlinear relativistic Hamiltonian. We use the semiexplicit integrator appearing in:

B. Jayawardana and T. Ohsawa, "Semiexplicit symplectic integrators for non-separable Hamiltonian systems," Math. Comput. 92, pp. 251-281 (2022),
https://doi.org/10.1090/mcom/3778 (arXiv)

To do:

  • add template for the basic VectorPotential element
  • add functions needed for the semiexplicit integrator
  • update the map in VectorPotential to use the correct Hamiltonian derivatives
  • update user-facing inputs
  • add simple benchmark problem(s)
  • check the treatment of s-dependence
  • add an s-dependent benchmark problem
  • add Python bindings
  • update documentation
  • add support for 4th-order and 6th-order integration

@cemitch99 cemitch99 marked this pull request as draft May 15, 2025 01:59
@cemitch99 cemitch99 marked this pull request as ready for review May 15, 2025 02:14
@ax3l ax3l self-requested a review June 18, 2025 18:48
@ax3l ax3l added component: elements Elements/maps/external fields tracking: particles labels Jun 18, 2025
@ax3l ax3l added this to the HTU LDRD milestone Jun 18, 2025
Comment thread src/elements/VectorPotential.H Fixed
@cemitch99 cemitch99 changed the title [WIP] Symplectic integration in a user-defined vector potential Symplectic integration in a user-defined vector potential Jul 17, 2025
Comment thread src/elements/VectorPotential.H Outdated
@ax3l ax3l force-pushed the development branch 2 times, most recently from 9a1e4af to fa61eba Compare April 20, 2026 04:08
@codspeed-hq

codspeed-hq Bot commented May 24, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 5.58%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 40 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
test_ExactDrift[spin] 645.1 µs 611 µs +5.58%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing cemitch99:add_user_nonlinear_element (0f461cf) with development (69c4e3e)

Open in CodSpeed

Comment thread .github/workflows/cuda.yml Outdated
Comment thread src/initialization/InitElement.cpp Outdated
Comment thread src/initialization/InitElement.cpp Outdated
Comment thread src/python/elements.cpp
* local frame. Reversing only negates the path-length integration
* direction; the user is responsible for the field's z-symmetry.
*/
void reverse () { Thick::reverse(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To check: complete or is there more to do? (needs a test entry in tests/python/test_reversibility_elements.py)

Comment thread examples/vector_potential/input_exact_quad_vector_potential.in Outdated
Comment thread examples/vector_potential/input_fodo_vector_potential.in Outdated
Comment thread examples/vector_potential/input_solenoid_vector_potential.in Outdated
ax3l added 2 commits May 24, 2026 22:18
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
@ax3l

ax3l commented May 25, 2026

Copy link
Copy Markdown
Member

@cemitch99 I updated this PR and test pass now :)

A few smaller inline comments remain.

Comment thread src/elements/MagnetostaticVectorPotential.H
Comment on lines +642 to +644
// Iteration loop (implicit step)
for (int j = 0; j < max_iterations; j++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex:

  • High: src/particles/integrators/Integrators.H:642 silently leaves particle
    unchanged if the fixed-point/Newton loop never reaches tolerance. This can
    turn a hard integration failure into a no-op push for that particle. I’d
    abort/report non-convergence, and make the tolerance precision-aware.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could be tricky within a GPU kernel. We could make particles invalid with signaling NaNs or whip up a detailed error machinery.

Comment thread src/python/elements.cpp
Comment on lines +2886 to +2893
.def("to_dict",
[](MagnetostaticVectorPotential const & vp) {
return element_dict(
vp,
std::make_pair("unit", vp.m_unit)
);
}
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex:

  • Medium: src/python/elements.cpp:2886 serializes only unit for
    MagnetostaticVectorPotential. ax, ay, derivative formulas, int_order, and
    mapsteps are dropped, so KnownElementsList.to_dicts()/from_dicts()
    reconstructs a different zero-field/default element. The new element should
    also be added to tests/python/test_element_serialization.py.

Comment thread docs/source/usage/python.rst Outdated
Comment on lines +1807 to +1809
.. py:property:: k

quadrupole strength in 1/m^2 (or T/m)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex:

  • Low: docs/source/usage/python.rst:1807 documents a nonexistent k property
    and describes unit as a quad strength unit. Also mapsteps is documented as
    default 5 in docs, while the C++/Python binding default is 10.

Comment on lines +408 to +412
void
finalize ()
{
DynamicData::registry().erase(m_id);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex:

  • Medium: src/elements/MagnetostaticVectorPotential.H:409 erases the parser
    registry entry during finalize(). Since elements are copied by value into
    the lattice, a user-held Python/C++ element object can still exist with the
    same m_id after sim.finalize(), but its parser data is gone. Reusing that
    element in a later simulation will fail in DynamicData::get(m_id). This also
    contradicts the comment at src/elements/MagnetostaticVectorPotential.H:44
    saying host data persists across simulations. A robust fix would keep the
    original formula strings as durable host data and rebuild AMReX parsers
    after a new initialize cycle.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes this pattern is wrong, needs to be a NoFinalize class. Will update.

Comment on lines +568 to +570
} else {

// initialize numerical integration parameters (int_order = 6)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex:

  • Medium: src/particles/integrators/Integrators.H:568 treats every int_order
    other than 2 or 4 as sixth order. Because the constructor, input parser, and
    Python setter accept arbitrary integers, int_order=3 or a typo silently
    changes the integration method. This should be else if (int_order == 6) plus
    an error, or validation in the element constructor/parser/setter.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree, and the setter/constructor should abort on orders that are not 2,4 or 6

Comment thread examples/vector_potential/README.rst Outdated

.. literalinclude:: analysis_fodo_vector_potential.py
:language: python3
:caption: You can copy this file from ``examples/vector_potential/analysis_vector_potential.py``.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Codex:

  • Low: examples/vector_potential/README.rst:45 has a stale caption pointing to
    analysis_vector_potential.py, but the included file is
    analysis_fodo_vector_potential.py.

Comment thread examples/vector_potential/README.rst Outdated
Comment thread src/elements/MagnetostaticVectorPotential.H Outdated
Comment thread docs/source/usage/python.rst Outdated
Comment thread docs/source/usage/python.rst Outdated
Comment thread docs/source/usage/python.rst Outdated
Co-authored-by: Chad Mitchell <46825199+cemitch99@users.noreply.github.com>
element.map(tau2,particle2,particle1,zeval2,zeval1);
element.map(tau1,particle1,particle2,zeval1,zeval2);

} else {

@cemitch99 cemitch99 May 30, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Suggested change
} else {
} else if (int_order==6) {

element.map(tau3,particle1,particle2,zeval1,zeval2);
element.map(tau2,particle2,particle1,zeval2,zeval1);
element.map(tau1,particle1,particle2,zeval1,zeval2);

@cemitch99 cemitch99 May 30, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Suggested change
} else {
// throw an error here

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

Labels

component: elements Elements/maps/external fields tracking: particles

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants