Skip to content

VTXWriter: support file modes#4177

Open
schnellerhase wants to merge 11 commits intomainfrom
schnellerhase/vtx-timeseries
Open

VTXWriter: support file modes#4177
schnellerhase wants to merge 11 commits intomainfrom
schnellerhase/vtx-timeseries

Conversation

@schnellerhase
Copy link
Copy Markdown
Contributor

@schnellerhase schnellerhase commented Apr 24, 2026

Adds support to ADIOS2Writer and VTXWriter to open files in append mode (following interface of VTKFile). Enabling usage such as

import dolfinx
from mpi4py import MPI

mesh = dolfinx.mesh.create_unit_square(comm := MPI.COMM_WORLD, n := 10, n)
V = dolfinx.fem.functionspace(mesh, ("CG", 1))
f = dolfinx.fem.Function(V)

# this usage previously only held the 9th iterate in the output, i.e. was not supported
for i in range(10):
    f.x.array[:] = i
    with dolfinx.io.VTXWriter(
        comm,
        "out_a.bp",
        "a",
        [f],
    ) as writer:
        writer.write(i)

# now holds equivalent output to:
with dolfinx.io.VTXWriter(
    comm,
    "out_w.bp",
    "w",
    [f],
) as writer:
    for i in range(10):
        f.x.array[:] = i
        writer.write(i)

Demonstrates the new feature, with simplified I/o logic in the naiver stokes demo.

@schnellerhase schnellerhase added enhancement New feature or request io labels Apr 24, 2026
@schnellerhase schnellerhase force-pushed the schnellerhase/vtx-timeseries branch 2 times, most recently from c274af4 to 1f68407 Compare April 24, 2026 13:05
@schnellerhase schnellerhase self-assigned this Apr 24, 2026
@schnellerhase schnellerhase marked this pull request as ready for review April 24, 2026 13:21
@schnellerhase schnellerhase requested a review from jorgensd April 24, 2026 13:21
@schnellerhase schnellerhase changed the title VTXWriter: enable append file writing VTXWriter: support file modes Apr 24, 2026
@schnellerhase schnellerhase force-pushed the schnellerhase/vtx-timeseries branch 2 times, most recently from e75536c to e350ed9 Compare April 24, 2026 13:36
@schnellerhase schnellerhase force-pushed the schnellerhase/vtx-timeseries branch from e350ed9 to 1911667 Compare April 24, 2026 13:55
Comment thread python/dolfinx/io/utils.py Outdated
if (mode == "a")
return adios2::Mode::Append;

if (mode == "w")
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.

else if and else?

Comment thread cpp/dolfinx/io/ADIOS2Writers.cpp Outdated
_engine->Close();
}
//-----------------------------------------------------------------------------
adios2::Mode impl_adios2::mode(const std::string& mode)
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.

Did you consider just wrapping adios2::Mode directly as an enum?

Copy link
Copy Markdown
Contributor Author

@schnellerhase schnellerhase May 2, 2026

Choose a reason for hiding this comment

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

The ADIOS2Writer operates directly on adios::Mode only the VTXWriter on the string. I understood the second as being the no longer adios2 interface specific implementation of dolfinx's interface, therefore not using the enum there.

Comment thread cpp/dolfinx/io/ADIOS2Writers.cpp Outdated
}

/// Convert string to corresponding adios2 mode.
/// @param[in] mode Mode in string representation, either "w" or "a".
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.

Leaving aside Enum vs no Enum, it's generally most transparent to map modes directly e.g. "Read" -> "adios2::Mode::Read". Then I have a clear idea what "Read" means in the context of the underlying library.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

r, w are the unix names for the operation and also what we use for the VTKFile interface.

@jorgensd
Copy link
Copy Markdown
Member

I'm a bit sceptical about adding an "append" mode, as the VTXScheme shouldn't (or at least couldn't previously) be modified at runtime with ADIOS2, which is why the initializer takes in the functions/meshes to store at each time-step, instead of following the XDMF file version where we write when we can.

adding an append-mode needs us to revise the internal logic to ensure for consistent input at multiple steps.
We would also have to thoroughly check which variables ADIOS2 now allows to be time-dependent (last section of https://adios2.readthedocs.io/en/latest/ecosystem/visualization.html)

@schnellerhase
Copy link
Copy Markdown
Contributor Author

I'm a bit sceptical about adding an "append" mode, as the VTXScheme shouldn't (or at least couldn't previously) be modified at runtime with ADIOS2, which is why the initializer takes in the functions/meshes to store at each time-step, instead of following the XDMF file version where we write when we can.

adding an append-mode needs us to revise the internal logic to ensure for consistent input at multiple steps. We would also have to thoroughly check which variables ADIOS2 now allows to be time-dependent (last section of https://adios2.readthedocs.io/en/latest/ecosystem/visualization.html)

I checked with the following script, which seems to correctly append to the xml contents (while currently duplicating everything though) of the VTXScheme. That should allow us to enable append mode writing in principle, right?

import dolfinx
from mpi4py import MPI

mesh = dolfinx.mesh.create_unit_square(comm := MPI.COMM_WORLD, n := 10, n)
V = dolfinx.fem.functionspace(mesh, ("CG", 1))
V2 = dolfinx.fem.functionspace(mesh, ("CG", 2))
f = dolfinx.fem.Function(V)
f.x.array[:] = 1
f2 = dolfinx.fem.Function(V2)
f2.x.array[:] = 2

with dolfinx.io.VTXWriter(
    comm,
    "out.bp",
    "w",
    [f],
) as writer:
    writer.write(0)


with dolfinx.io.VTXWriter(
    comm,
    "out.bp",
    "a",
    [f2],
) as writer:
    writer.write(1)

from adios2 import Stream

with Stream("out.bp", "r") as s:
    # steps comes from the stream
    for _ in s.steps():
        # track current step
        print(f"Current step is {s.current_step()}")

        # inspect variables in current step
        # for name, info in s.available_variables().items():
        #     print("variable_name: " + name, end=" ")
        #     for key, value in info.items():
        #         print("\t" + key + ": " + value, end=" ")
        #     print()

        xml = s.read_attribute("vtk.xml")
        print(xml)

Output:

Current step is 0
<?xml version="1.0"?>
<VTKFile type="UnstructuredGrid" version="0.1">
  <UnstructuredGrid>
    <Piece NumberOfPoints="NumberOfNodes" NumberOfCells="NumberOfCells">
      <Points>
        <DataArray Name="geometry" />
      </Points>
      <Cells>
        <DataArray Name="connectivity" />
        <DataArray Name="types" />
      </Cells>
      <PointData>
        <DataArray Name="TIME">step</DataArray>
        <DataArray Name="vtkOriginalPointIds" />
        <DataArray Name="vtkGhostType" />
        <DataArray Name="f" />
      </PointData>
    </Piece>
  </UnstructuredGrid>
</VTKFile>

Current step is 1
<?xml version="1.0"?>
<VTKFile type="UnstructuredGrid" version="0.1">
  <UnstructuredGrid>
    <Piece NumberOfPoints="NumberOfNodes" NumberOfCells="NumberOfCells">
      <Points>
        <DataArray Name="geometry" />
      </Points>
      <Cells>
        <DataArray Name="connectivity" />
        <DataArray Name="types" />
      </Cells>
      <PointData>
        <DataArray Name="TIME">step</DataArray>
        <DataArray Name="vtkOriginalPointIds" />
        <DataArray Name="vtkGhostType" />
        <DataArray Name="f" />
      </PointData>
    </Piece>
  </UnstructuredGrid>
</VTKFile>

@jorgensd
Copy link
Copy Markdown
Member

jorgensd commented May 4, 2026

@schnellerhase They did change how attributes work in adios2 a while ago (ornladios/ADIOS2#4471) which blurred the lines between variables and attributes, which I guess it makes it work.

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

Labels

enhancement New feature or request io

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants