From 5ab05dfdcec581fa6b39e23a91a1394089ca243c Mon Sep 17 00:00:00 2001 From: GardevoirX Date: Mon, 23 Mar 2026 15:18:13 +0100 Subject: [PATCH 1/2] Indicate i-pi can provide momenta/velocities as inputs --- docs/src/outputs/momenta.rst | 8 ++++++++ docs/src/outputs/velocities.rst | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/docs/src/outputs/momenta.rst b/docs/src/outputs/momenta.rst index cc74eb525..8d3a1a76e 100644 --- a/docs/src/outputs/momenta.rst +++ b/docs/src/outputs/momenta.rst @@ -59,3 +59,11 @@ The following simulation engine can provide ``"momenta"`` as inputs to the model :link-type: ref |ase-logo| + + .. grid-item-card:: + :text-align: center + :padding: 1 + :link: engine-ipi + :link-type: ref + + |ipi-logo| diff --git a/docs/src/outputs/velocities.rst b/docs/src/outputs/velocities.rst index 7e0834f98..c3d22d4e2 100644 --- a/docs/src/outputs/velocities.rst +++ b/docs/src/outputs/velocities.rst @@ -55,3 +55,11 @@ The following simulation engine can provide ``"velocities"`` as inputs to the mo :link-type: ref |ase-logo| + + .. grid-item-card:: + :text-align: center + :padding: 1 + :link: engine-ipi + :link-type: ref + + |ipi-logo| From e0acbcf4ff4d7b56790c10e69ca5c7543da6379f Mon Sep 17 00:00:00 2001 From: GardevoirX Date: Mon, 23 Mar 2026 15:18:53 +0100 Subject: [PATCH 2/2] Add heat_flux as a standard output --- docs/src/outputs/heat_flux.rst | 61 ++++++++++++++++++++++++ docs/src/outputs/index.rst | 10 ++++ docs/static/images/heat-flux-output.png | Bin 0 -> 19878 bytes metatomic-torch/src/misc.cpp | 1 + metatomic-torch/src/outputs.cpp | 40 ++++++++++++++++ metatomic-torch/src/units.cpp | 17 +++---- metatomic-torch/tests/models.cpp | 2 +- 7 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 docs/src/outputs/heat_flux.rst create mode 100644 docs/static/images/heat-flux-output.png diff --git a/docs/src/outputs/heat_flux.rst b/docs/src/outputs/heat_flux.rst new file mode 100644 index 000000000..b5d04965e --- /dev/null +++ b/docs/src/outputs/heat_flux.rst @@ -0,0 +1,61 @@ +.. _heat-flux-output: + +Heat Flux +^^^^^^^^^ + +Heat flux is associated with the ``"heat_flux"`` or ``"heat_flux/"`` +name (see :ref:`output-variants`), and must have the following metadata: + +.. list-table:: Metadata for heat fluxes + :widths: 2 3 7 + :header-rows: 1 + + * - Metadata + - Names + - Description + + * - keys + - ``"_"`` + - the keys must have a single dimension named ``"_"``, with a single + entry set to ``0``. Heat fluxes are always a + :py:class:`metatensor.torch.TensorMap` with a single block. + + * - samples + - ``["system"]`` + - the samples must be named ``["system"]``, since heat fluxes are always + per-system. + + ``"system"`` must range from 0 to the number of systems given as an input + to the model. + + * - components + - ``"xyz"`` + - heat fluxes must have a single component dimension named + ``"xyz"``, with three entries set to ``0``, ``1``, and ``2``. The + heat fluxes are always 3D vectors, and the order of the + components is x, y, z. + + * - properties + - ``"heat_flux"`` + - heat fluxes must have a single property dimension named + ``"heat_flux"``, with a single entry set to ``0``. + +The following simulation engine can use the ``"heat_flux"`` output. + +.. grid:: 1 3 3 3 + + .. grid-item-card:: + :text-align: center + :padding: 1 + :link: engine-ase + :link-type: ref + + |ase-logo| + + .. grid-item-card:: + :text-align: center + :padding: 1 + :link: engine-ipi + :link-type: ref + + |ipi-logo| diff --git a/docs/src/outputs/index.rst b/docs/src/outputs/index.rst index 8b6ec11fa..8a68800c1 100644 --- a/docs/src/outputs/index.rst +++ b/docs/src/outputs/index.rst @@ -25,6 +25,7 @@ schema they need and add a new section to these pages. momenta velocities charges + heat_flux features variants @@ -131,6 +132,15 @@ quantities, i.e. quantities with a well-defined physical meaning. Atomic charges, e.g. formal or partial charges on atoms + .. grid-item-card:: Heat flux + :link: heat-flux-output + :link-type: ref + + .. image:: /../static/images/heat-flux-output.png + + Heat flux, i.e. the amount of energy transferred per unit time, i.e. + :math:`\sum_i E_i \times \vec v_i` + Machine learning quantities ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/static/images/heat-flux-output.png b/docs/static/images/heat-flux-output.png new file mode 100644 index 0000000000000000000000000000000000000000..52a7f040f6d351679cdb31c8dd27c025e51a694b GIT binary patch literal 19878 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 literal 0 HcmV?d00001 diff --git a/metatomic-torch/src/misc.cpp b/metatomic-torch/src/misc.cpp index ab4a24982..647b685e6 100644 --- a/metatomic-torch/src/misc.cpp +++ b/metatomic-torch/src/misc.cpp @@ -427,6 +427,7 @@ inline std::unordered_set KNOWN_INPUTS_OUTPUTS = { "velocities", "masses", "charges", + "heat_flux", }; std::tuple details::validate_name_and_check_variant( diff --git a/metatomic-torch/src/outputs.cpp b/metatomic-torch/src/outputs.cpp index 86aa23f1e..9ed8fcd35 100644 --- a/metatomic-torch/src/outputs.cpp +++ b/metatomic-torch/src/outputs.cpp @@ -584,6 +584,44 @@ static void check_charges( validate_no_gradients("charges", charges_block); } +/// Check output metadata for heat flux. +static void check_heat_flux( + const TensorMap& value, + const std::vector& systems, + const ModelOutput& request +) { + // Ensure the output contains a single block with the expected key + validate_single_block("heat_flux", value); + + // Check samples values from systems + if (request->per_atom) { + C10_THROW_ERROR(ValueError, + "invalid 'heat_flux' output: heat flux cannot be per-atom, but the request " + "indicates `per_atom=True`" + ); + } + validate_atomic_samples("heat_flux", value, systems, request, torch::nullopt); + + auto tensor_options = torch::TensorOptions().device(value->device()); + auto heat_flux_block = TensorMapHolder::block_by_id(value, 0); + std::vector expected_component { + torch::make_intrusive( + "xyz", + torch::tensor({{0}, {1}, {2}}, tensor_options) + ) + }; + validate_components("heat_flux", heat_flux_block->components(), expected_component); + + auto expected_properties = torch::make_intrusive( + "heat_flux", + torch::tensor({{0}}, tensor_options) + ); + validate_properties("heat_flux", heat_flux_block, expected_properties); + + // Should not have any gradients + validate_no_gradients("heat_flux", heat_flux_block); +} + void metatomic_torch::check_outputs( const std::vector& systems, const c10::Dict& requested, @@ -654,6 +692,8 @@ void metatomic_torch::check_outputs( check_velocities(value, systems, request); } else if (base == "charges") { check_charges(value, systems, request); + } else if (base == "heat_flux") { + check_heat_flux(value, systems, request); } else if (name.find("::") != std::string::npos) { // this is a non-standard output, there is nothing to check } else { diff --git a/metatomic-torch/src/units.cpp b/metatomic-torch/src/units.cpp index 5d277fc9d..bd74e1ac6 100644 --- a/metatomic-torch/src/units.cpp +++ b/metatomic-torch/src/units.cpp @@ -586,14 +586,15 @@ static UnitValue parse_unit_expression(const std::string& unit) { static const auto QUANTITY_DIMS = std::unordered_map{ - {"length", DIM_LENGTH}, - {"energy", DIM_ENERGY}, - {"force", {{1, -2, 1, 0, 0}}}, // energy/length - {"pressure", {{-1, -2, 1, 0, 0}}}, // energy/length^3 - {"momentum", {{1, -1, 1, 0, 0}}}, // mass*length/time - {"mass", DIM_MASS}, - {"velocity", {{1, -1, 0, 0, 0}}}, // length/time - {"charge", DIM_CHARGE}, + {"length", DIM_LENGTH}, + {"energy", DIM_ENERGY}, + {"force", {{1, -2, 1, 0, 0}}}, // energy/length + {"pressure", {{-1, -2, 1, 0, 0}}}, // energy/length^3 + {"momentum", {{1, -1, 1, 0, 0}}}, // mass*length/time + {"mass", DIM_MASS}, + {"velocity", {{1, -1, 0, 0, 0}}}, // length/time + {"charge", DIM_CHARGE}, + {"heat_flux", {{3, -3, 1, 0, 0}}}, // energy*velocity }; diff --git a/metatomic-torch/tests/models.cpp b/metatomic-torch/tests/models.cpp index ec8ec46f5..c319b6593 100644 --- a/metatomic-torch/tests/models.cpp +++ b/metatomic-torch/tests/models.cpp @@ -110,7 +110,7 @@ TEST_CASE("Models metadata") { virtual ~WarningHandler() override = default; void process(const torch::Warning& warning) override { auto expected = std::string( - "unknown quantity 'unknown', only [charge energy force " + "unknown quantity 'unknown', only [charge energy force heat_flux " "length mass momentum pressure velocity] are supported" ); CHECK(warning.msg() == expected);