Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cpp/demo/interpolation-io/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ void interpolate_scalar(std::shared_ptr<mesh::Mesh<U>> mesh,
#ifdef HAS_ADIOS2
// Write the function to a VTX file for visualisation, e.g. using
// ParaView
io::VTXWriter<U> outfile(mesh->comm(), filename.replace_extension("bp"), {u},
"BP4");
io::VTXWriter<U> outfile(mesh->comm(), filename.replace_extension("bp"), "w",
{u}, "BP4");
outfile.write(0);
outfile.close();
#endif
Expand Down Expand Up @@ -183,7 +183,7 @@ void interpolate_nedelec(std::shared_ptr<mesh::Mesh<U>> mesh,
// (jump in the normal component between cells) and the x1 component
// will appear continuous (continuous tangent component between cells).
#ifdef HAS_ADIOS2
io::VTXWriter<U> outfile(mesh->comm(), filename.replace_extension("bp"),
io::VTXWriter<U> outfile(mesh->comm(), filename.replace_extension("bp"), "w",
{u_l}, "BP4");
outfile.write(0);
outfile.close();
Expand Down
4 changes: 2 additions & 2 deletions cpp/demo/interpolation_different_meshes/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ int main(int argc, char* argv[])
u_hex->interpolate(*u_tet, cells, eps, max_iter, interpolation_data);

#ifdef HAS_ADIOS2
io::VTXWriter<double> write_tet(mesh_tet->comm(), "u_tet.bp", {u_tet});
io::VTXWriter<double> write_tet(mesh_tet->comm(), "u_tet.bp", "w", {u_tet});
write_tet.write(0);
io::VTXWriter<double> write_hex(mesh_hex->comm(), "u_hex.bp", {u_hex});
io::VTXWriter<double> write_hex(mesh_hex->comm(), "u_hex.bp", "w", {u_hex});
write_hex.write(0);
#endif
}
Expand Down
4 changes: 2 additions & 2 deletions cpp/demo/mixed_poisson/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,10 @@ int main(int argc, char* argv[])

#ifdef HAS_ADIOS2
// Save solution in VTX format
io::VTXWriter<U> vtx_u(MPI_COMM_WORLD, "u.bp", {u_soln}, "bp4");
io::VTXWriter<U> vtx_u(MPI_COMM_WORLD, "u.bp", "w", {u_soln}, "bp4");
vtx_u.write(0);
// Save interpolated boundary condition
io::VTXWriter<U> vtx_u0(MPI_COMM_WORLD, "u0.bp", {u0}, "bp4");
io::VTXWriter<U> vtx_u0(MPI_COMM_WORLD, "u0.bp", "w", {u0}, "bp4");
vtx_u0.write(0);
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion cpp/demo/poisson/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ int main(int argc, char* argv[])

#ifdef HAS_ADIOS2
// Save solution in VTX format
io::VTXWriter<U> vtx(MPI_COMM_WORLD, "u.bp", {u}, "bp4");
io::VTXWriter<U> vtx(MPI_COMM_WORLD, "u.bp", "w", {u}, "bp4");
vtx.write(0);
#endif
}
Expand Down
24 changes: 21 additions & 3 deletions cpp/dolfinx/io/ADIOS2Writers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@

//-----------------------------------------------------------------------------
ADIOS2Writer::ADIOS2Writer(MPI_Comm comm, const std::filesystem::path& filename,
std::string tag, std::string engine)
adios2::Mode mode, std::string tag,
std::string engine)
: _adios(std::make_unique<adios2::ADIOS>(comm)),
_io(std::make_unique<adios2::IO>(_adios->DeclareIO(std::move(tag))))
{
_io->SetEngine(std::move(engine));
_engine = std::make_unique<adios2::Engine>(
_io->Open(filename, adios2::Mode::Write));
_engine = std::make_unique<adios2::Engine>(_io->Open(filename, mode));
}
//-----------------------------------------------------------------------------
ADIOS2Writer::~ADIOS2Writer() { close(); }
Expand All @@ -38,6 +38,24 @@
_engine->Close();
}
//-----------------------------------------------------------------------------
adios2::Mode impl_adios2::mode(const std::string& mode)

Check warning on line 41 in cpp/dolfinx/io/ADIOS2Writers.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this const reference to "std::string" by a "std::string_view".

See more on https://sonarcloud.io/project/issues?id=FEniCS_dolfinx&issues=AZ2_lSmJIi-uh0GvPQ2W&open=AZ2_lSmJIi-uh0GvPQ2W&pullRequest=4177
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
Member

Choose a reason for hiding this comment

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

Use non-owning std::string_view

{
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?

return adios2::Mode::Write;

// unsupported adios2 modes:
// - Undefined
// - Read
// - ReadRandomAccess
// - Sync
// - Deferred

throw std::runtime_error("Invalid adios2 mode.");

Check warning on line 56 in cpp/dolfinx/io/ADIOS2Writers.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=FEniCS_dolfinx&issues=AZ2_lSmJIi-uh0GvPQ2X&open=AZ2_lSmJIi-uh0GvPQ2X&pullRequest=4177
}
//-----------------------------------------------------------------------------
std::stringstream
io::impl_vtx::create_vtk_schema(const std::vector<std::string>& point_data,
const std::vector<std::string>& cell_data)
Expand Down
29 changes: 21 additions & 8 deletions cpp/dolfinx/io/ADIOS2Writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "vtk_utils.h"
#include <adios2.h>
#include <adios2/common/ADIOSTypes.h>
#include <algorithm>
#include <basix/mdspan.hpp>
#include <cassert>
Expand Down Expand Up @@ -59,11 +60,12 @@ class ADIOS2Writer
/// @brief Create an ADIOS2-based writer
/// @param[in] comm The MPI communicator
/// @param[in] filename Name of output file
/// @param[in] mode Mode to open file with
/// @param[in] tag The ADIOS2 object name
/// @param[in] engine ADIOS2 engine type. See
/// https://adios2.readthedocs.io/en/latest/engines/engines.html.
ADIOS2Writer(MPI_Comm comm, const std::filesystem::path& filename,
std::string tag, std::string engine);
adios2::Mode mode, std::string tag, std::string engine);

/// @brief Move constructor
ADIOS2Writer(ADIOS2Writer&& writer) = default;
Expand Down Expand Up @@ -157,6 +159,11 @@ extract_common_mesh(const typename adios2_writer::U<T>& u)
return mesh;
}

/// 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.

/// @returns Adios2 mode.
adios2::Mode mode(const std::string& mode);

} // namespace impl_adios2

/// @privatesection
Expand Down Expand Up @@ -461,16 +468,18 @@ class VTXWriter : public ADIOS2Writer
///
/// @param[in] comm MPI communicator to open the file on.
/// @param[in] filename Name of output file.
/// @param[in] mode Mode to open file with
/// @param[in] mesh Mesh to write.
/// @param[in] engine ADIOS2 engine type.
/// @note This format supports arbitrary degree meshes.
/// @note The mesh geometry can be updated between write steps but the
/// topology should not be changed between write steps.
VTXWriter(MPI_Comm comm, const std::filesystem::path& filename,
std::shared_ptr<const mesh::Mesh<T>> mesh,
const std::string& mode, std::shared_ptr<const mesh::Mesh<T>> mesh,
std::string engine = "BPFile")
: ADIOS2Writer(comm, filename, "VTX mesh writer", engine), _mesh(mesh),
_mesh_reuse_policy(VTXMeshPolicy::update),
: ADIOS2Writer(comm, filename, impl_adios2::mode(mode), "VTX mesh writer",
engine),
_mesh(mesh), _mesh_reuse_policy(VTXMeshPolicy::update),
_has_piecewise_constant(false)
{
// Define VTK scheme attribute for mesh
Expand All @@ -484,6 +493,7 @@ class VTXWriter : public ADIOS2Writer
///
/// @param[in] comm The MPI communicator to open the file on
/// @param[in] filename Name of output file
/// @param[in] mode Mode to open file with
/// @param[in] u List of functions. The functions must (1) share the
/// same mesh and (2) be (discontinuous) Lagrange functions. The
/// element family and degree, and degree-of-freedom map (up to the
Expand All @@ -494,9 +504,11 @@ class VTXWriter : public ADIOS2Writer
/// step.
/// @note This format supports arbitrary degree meshes.
VTXWriter(MPI_Comm comm, const std::filesystem::path& filename,
const typename adios2_writer::U<T>& u, std::string engine,
const std::string& mode, const typename adios2_writer::U<T>& u,
std::string engine,
VTXMeshPolicy mesh_policy = VTXMeshPolicy::update)
: ADIOS2Writer(comm, filename, "VTX function writer", engine),
: ADIOS2Writer(comm, filename, impl_adios2::mode(mode),
"VTX function writer", engine),
_mesh(impl_adios2::extract_common_mesh<T>(u)), _u(u),
_mesh_reuse_policy(mesh_policy), _has_piecewise_constant(false)
{
Expand Down Expand Up @@ -595,6 +607,7 @@ class VTXWriter : public ADIOS2Writer
///
/// @param[in] comm The MPI communicator to open the file on
/// @param[in] filename Name of output file
/// @param[in] mode Mode to open file with
/// @param[in] u List of functions. The functions must (1) share the
/// same mesh and (2) be (discontinuous) Lagrange functions. The
/// element family and degree must be the same for all functions.
Expand All @@ -603,9 +616,9 @@ class VTXWriter : public ADIOS2Writer
/// step.
/// @note This format supports arbitrary degree meshes.
VTXWriter(MPI_Comm comm, const std::filesystem::path& filename,
const typename adios2_writer::U<T>& u,
const std::string& mode, const typename adios2_writer::U<T>& u,
VTXMeshPolicy mesh_policy = VTXMeshPolicy::update)
: VTXWriter(comm, filename, u, "BPFile", mesh_policy)
: VTXWriter(comm, filename, mode, u, "BPFile", mesh_policy)
{
}

Expand Down
2 changes: 1 addition & 1 deletion cpp/test/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void test_vtx_reuse_mesh()

std::filesystem::path f
= "test_vtx_reuse_mesh" + std::to_string(sizeof(T)) + ".bp";
io::VTXWriter<T> writer(mesh->comm(), f, {u, v}, "BPFile",
io::VTXWriter<T> writer(mesh->comm(), f, "w", {u, v}, "BPFile",
io::VTXMeshPolicy::reuse);
writer.write(0);

Expand Down
2 changes: 1 addition & 1 deletion python/demo/demo_axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,6 @@ def create_eps_mu(pml, rho, eps_bkg, mu_bkg):
Es_dg = fem.Function(W)
Es_expr = fem.Expression(Esh, W.element.interpolation_points)
Es_dg.interpolate(Es_expr)
with VTXWriter(mesh_data.mesh.comm, out_folder / "Es.bp", Es_dg) as f:
with VTXWriter(mesh_data.mesh.comm, out_folder / "Es.bp", "w", Es_dg) as f:
f.write(0.0)
# -
2 changes: 1 addition & 1 deletion python/demo/demo_biharmonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@
if has_adios2:
out_folder = Path("out_biharmonic")
out_folder.mkdir(parents=True, exist_ok=True)
with io.VTXWriter(msh.comm, out_folder / "biharmonic.bp", [uh]) as file:
with io.VTXWriter(msh.comm, out_folder / "biharmonic.bp", "w", [uh]) as file:
file.write(0.0)

# and displayed using [pyvista](https://docs.pyvista.org/).
Expand Down
4 changes: 2 additions & 2 deletions python/demo/demo_half_loaded_waveguide.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,10 @@ def verify_mode(

if has_vtx:
# Save solutions
with VTXWriter(msh.comm, out_folder / f"Et_{i}.bp", Et_dg) as f:
with VTXWriter(msh.comm, out_folder / f"Et_{i}.bp", "w", Et_dg) as f:
f.write(0.0)

with VTXWriter(msh.comm, out_folder / f"Ez_{i}.bp", ezh) as f:
with VTXWriter(msh.comm, out_folder / f"Ez_{i}.bp", "w", ezh) as f:
f.write(0.0)

# Visualize solutions with Pyvista
Expand Down
4 changes: 2 additions & 2 deletions python/demo/demo_hdg.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,9 @@ def u_e(x):
if dolfinx.has_adios2:
from dolfinx.io import VTXWriter

with VTXWriter(msh.comm, "u.bp", u, "bp4") as f:
with VTXWriter(msh.comm, "u.bp", "w", u, "bp4") as f:
f.write(0.0)
with VTXWriter(msh.comm, "ubar.bp", ubar, "bp4") as f:
with VTXWriter(msh.comm, "ubar.bp", "w", ubar, "bp4") as f:
f.write(0.0)
else:
print("ADIOS2 required for VTX output")
Expand Down
2 changes: 1 addition & 1 deletion python/demo/demo_interpolation-io.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
if has_adios2:
from dolfinx.io import VTXWriter

with VTXWriter(msh.comm, out_folder / "output_nedelec.bp", u0) as f:
with VTXWriter(msh.comm, out_folder / "output_nedelec.bp", "w", u0) as f:
f.write(0.0)
else:
print("ADIOS2 required for VTX output")
Expand Down
2 changes: 1 addition & 1 deletion python/demo/demo_mixed-poisson.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@
if dolfinx.has_adios2:
from dolfinx.io import VTXWriter

with VTXWriter(msh.comm, "output_mixed_poisson.bp", u) as f:
with VTXWriter(msh.comm, "output_mixed_poisson.bp", "w", u) as f:
f.write(0.0)
else:
print("ADIOS2 required for VTX output.")
Expand Down
20 changes: 8 additions & 12 deletions python/demo/demo_navier-stokes.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,10 @@ def jump(phi, n):
if has_adios2:
u_vis = fem.Function(W, name="u_init")
u_vis.interpolate(u_h)
u_file = io.VTXWriter(msh.comm, "u.bp", u_vis)
p_file = io.VTXWriter(msh.comm, "p.bp", p_h)
u_file.write(t)
p_file.write(t)
with io.VTXWriter(msh.comm, "u.bp", "w", u_vis) as file:
file.write(t)
with io.VTXWriter(msh.comm, "p.bp", "w", p_h) as file:
file.write(t)
else:
print("File output requires ADIOS2.")

Expand Down Expand Up @@ -422,17 +422,13 @@ def jump(phi, n):
# Write to file
if has_adios2:
u_vis.interpolate(u_h)
u_file.write(t)
p_file.write(t)
with io.VTXWriter(msh.comm, "u.bp", "a", u_vis) as file:
file.write(t)
with io.VTXWriter(msh.comm, "p.bp", "a", u_vis) as file:
file.write(t)

# Update u_n
u_n.x.array[:] = u_h.x.array

try:
u_file.close()
p_file.close()
except NameError:
pass
# -

# Now we compare the computed solution to the exact solution
Expand Down
4 changes: 2 additions & 2 deletions python/demo/demo_pml.py
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ def create_eps_mu(
Esh_dg = fem.Function(V_dg)
Esh_dg.interpolate(Esh)

with VTXWriter(mesh_data.mesh.comm, out_folder / "Esh.bp", Esh_dg) as vtx:
with VTXWriter(mesh_data.mesh.comm, out_folder / "Esh.bp", "w", Esh_dg) as vtx:
vtx.write(0.0)
# -

Expand Down Expand Up @@ -702,7 +702,7 @@ def create_eps_mu(
E_dg = fem.Function(V_dg)
E_dg.interpolate(E)

with VTXWriter(mesh_data.mesh.comm, out_folder / "E.bp", E_dg) as vtx:
with VTXWriter(mesh_data.mesh.comm, out_folder / "E.bp", "w", E_dg) as vtx:
vtx.write(0.0)
# -

Expand Down
4 changes: 2 additions & 2 deletions python/demo/demo_scattering_boundary_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ def curl_2d(f: fem.Function):
assert isinstance(Esh, fem.Function)
Esh_dg.interpolate(Esh)

with io.VTXWriter(mesh_data.mesh.comm, out_folder / "Esh.bp", Esh_dg) as vtx:
with io.VTXWriter(mesh_data.mesh.comm, out_folder / "Esh.bp", "w", Esh_dg) as vtx:
vtx.write(0.0)
# -

Expand Down Expand Up @@ -694,7 +694,7 @@ def curl_2d(f: fem.Function):
E.x.array[:] = Eb.x.array[:] + Esh.x.array[:]
E_dg = fem.Function(V_dg)
E_dg.interpolate(E)
with io.VTXWriter(mesh_data.mesh.comm, "E.bp", E_dg) as vtx:
with io.VTXWriter(mesh_data.mesh.comm, "E.bp", "w", E_dg) as vtx:
vtx.write(0.0)
# -

Expand Down
9 changes: 7 additions & 2 deletions python/dolfinx/io/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(
self,
comm: _MPI.Comm,
filename: str | Path,
mode: str,
output: Mesh | Function | list[Function] | tuple[Function],
engine: str = "BPFile",
mesh_policy: VTXMeshPolicy = VTXMeshPolicy.update,
Expand All @@ -56,6 +57,8 @@ def __init__(
Args:
comm: The MPI communicator
filename: The output filename
mode: The filemode to open the file in, one of 'a' (append)
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.

Remove "one of", automatic when using "or".

or 'w' (write).
output: The data to output. Either a mesh, a single
(discontinuous) Lagrange Function or list of
(discontinuous) Lagrange Functions.
Expand Down Expand Up @@ -87,14 +90,16 @@ def __init__(
raise RuntimeError(f"VTXWriter does not support dtype={dtype}.")

if isinstance(output, Mesh):
self._cpp_object = _vtxwriter(comm, filename, output._cpp_object, engine) # type: ignore[union-attr]
self._cpp_object = _vtxwriter(comm, filename, mode, output._cpp_object, engine) # type: ignore[union-attr]
else:
cpp_objects = (
[output._cpp_object]
if isinstance(output, Function)
else [o._cpp_object for o in output]
)
self._cpp_object = _vtxwriter(comm, filename, cpp_objects, engine, mesh_policy)
self._cpp_object = _vtxwriter(
comm, filename, mode, cpp_objects, engine, mesh_policy
)

def __enter__(self):
"""Enter context manager."""
Expand Down
Loading
Loading